Детальний посібник з JavaScript Temporal API, сучасного рішення для ефективної роботи з датами та часом у різноманітних міжнародних контекстах.
JavaScript Temporal API: Сучасна обробка дати та часу для глобальної аудиторії
Об'єкт `Date` в JavaScript давно є джерелом розчарування для розробників. Його мінливість, непослідовний API та погана підтримка часових поясів призвели до появи численних бібліотек, таких як Moment.js та date-fns, щоб заповнити прогалини. Тепер, з появою Temporal API, JavaScript пропонує сучасне вбудоване рішення для роботи з датами та часом з покращеною ясністю та точністю. Ця стаття надає комплексний огляд Temporal API, зосереджуючись на його функціях, перевагах та використанні в різноманітних міжнародних контекстах.
Що таке Temporal API?
Temporal API — це новий глобальний об'єкт у JavaScript, розроблений для усунення недоліків об'єкта `Date`. Він надає чистий, незмінний API для роботи з датами, часом, часовими поясами та календарними системами. Важливо те, що він має на меті представити концепції дати й часу у спосіб, який більше відповідає реальному використанню та очікуванням, що значно спрощує інтернаціоналізацію.
Ключові особливості:
- Незмінність (Immutability): Об'єкти Temporal є незмінними, що означає, що операції, такі як додавання днів або місяців, повертають нові об'єкти, а не модифікують оригінальний. Це усуває поширене джерело помилок і робить код легшим для розуміння.
- Чіткий API: Temporal надає послідовний та інтуїтивно зрозумілий API для поширених операцій з датою та часом.
- Підтримка часових поясів: Temporal включає надійну підтримку часових поясів, що дозволяє працювати з датами та часом у різних місцях без складнощів старого об'єкта `Date`. Він використовує базу даних часових поясів IANA, забезпечуючи точну та актуальну інформацію.
- Календарні системи: Окрім григоріанського календаря, Temporal підтримує альтернативні календарні системи, задовольняючи потреби різноманітних культур та регіонів.
- Покращена точність: Temporal пропонує наносекундну точність, вирішуючи обмеження об'єкта `Date`, що базується на мілісекундах.
Основні об'єкти Temporal
Temporal API вводить декілька нових типів об'єктів. Ось деякі з основних:
- `Temporal.PlainDate`: Представляє дату (рік, місяць, день) без часового поясу.
- `Temporal.PlainTime`: Представляє час (година, хвилина, секунда, мілісекунда, мікросекунда, наносекунда) без дати чи часового поясу.
- `Temporal.PlainDateTime`: Представляє дату та час без часового поясу.
- `Temporal.ZonedDateTime`: Представляє дату та час з конкретним часовим поясом.
- `Temporal.Instant`: Представляє конкретний момент у часі, виміряний у наносекундах з початку епохи Unix (1 січня 1970 року UTC).
- `Temporal.TimeZone`: Представляє часовий пояс.
- `Temporal.Duration`: Представляє проміжок часу (наприклад, 2 години, 30 хвилин).
- `Temporal.YearMonth`: Представляє рік та місяць.
- `Temporal.MonthDay`: Представляє місяць та день.
Робота з датами
Створення `Temporal.PlainDate`
Щоб створити `Temporal.PlainDate`, можна використати конструктор:
const plainDate = new Temporal.PlainDate(2024, 10, 27); // Рік, Місяць (1-12), День
console.log(plainDate.toString()); // Вивід: 2024-10-27
Також можна використовувати метод `from`, який приймає рядок у форматі ISO 8601:
const plainDateFromString = Temporal.PlainDate.from('2024-10-27');
console.log(plainDateFromString.toString()); // Вивід: 2024-10-27
Отримання компонентів дати
Ви можете отримати доступ до окремих компонентів дати за допомогою властивостей, таких як `year`, `month` та `day`:
console.log(plainDate.year); // Вивід: 2024
console.log(plainDate.month); // Вивід: 10
console.log(plainDate.day); // Вивід: 27
Арифметика дат
Щоб додати або відняти дні, тижні, місяці або роки, використовуйте методи `plus` та `minus`. Ці методи повертають новий об'єкт `Temporal.PlainDate`:
const nextWeek = plainDate.plus({ days: 7 });
console.log(nextWeek.toString()); // Вивід: 2024-11-03
const lastMonth = plainDate.minus({ months: 1 });
console.log(lastMonth.toString()); // Вивід: 2024-09-27
Порівняння дат
Ви можете порівнювати дати за допомогою методу `compare`:
const date1 = new Temporal.PlainDate(2024, 10, 27);
const date2 = new Temporal.PlainDate(2024, 11, 15);
console.log(Temporal.PlainDate.compare(date1, date2)); // Вивід: -1 (date1 раніше, ніж date2)
Робота з часом
Створення `Temporal.PlainTime`
Щоб створити `Temporal.PlainTime`, використовуйте конструктор:
const plainTime = new Temporal.PlainTime(10, 30, 0); // Година, Хвилина, Секунда
console.log(plainTime.toString()); // Вивід: 10:30:00
Або використовуйте метод `from` з рядком часу у форматі ISO 8601:
const plainTimeFromString = Temporal.PlainTime.from('10:30:00');
console.log(plainTimeFromString.toString()); // Вивід: 10:30:00
Отримання компонентів часу
console.log(plainTime.hour); // Вивід: 10
console.log(plainTime.minute); // Вивід: 30
console.log(plainTime.second); // Вивід: 0
Арифметика часу
const later = plainTime.plus({ minutes: 15 });
console.log(later.toString()); // Вивід: 10:45:00
Робота з датою та часом разом
Створення `Temporal.PlainDateTime`
Ви можете створити `Temporal.PlainDateTime` напряму або шляхом об'єднання `Temporal.PlainDate` та `Temporal.PlainTime`:
const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
console.log(plainDateTime.toString()); // Вивід: 2024-10-27T10:30:00
const date = new Temporal.PlainDate(2024, 10, 27);
const time = new Temporal.PlainTime(10, 30, 0);
const combinedDateTime = date.toPlainDateTime(time);
console.log(combinedDateTime.toString()); // Вивід: 2024-10-27T10:30:00
Часові пояси
Правильна обробка часових поясів є надзвичайно важливою для додатків, що працюють з користувачами в різних місцях. Temporal API надає надійну підтримку часових поясів через об'єкти `Temporal.ZonedDateTime` та `Temporal.TimeZone`.
Створення `Temporal.ZonedDateTime`
Для створення `Temporal.ZonedDateTime` вам знадобиться `Temporal.PlainDateTime` та ідентифікатор часового поясу. Ідентифікатори часових поясів базуються на базі даних часових поясів IANA (наприклад, `America/Los_Angeles`, `Europe/London`, `Asia/Tokyo`).
const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);
console.log(zonedDateTime.toString()); // Вивід: 2024-10-27T10:30:00-07:00[America/Los_Angeles] (Зсув залежатиме від правил переходу на літній час)
Як альтернатива, створіть `Temporal.ZonedDateTime` з `Instant`.
const instant = Temporal.Instant.fromEpochSeconds(1666866600); // Приклад мітки часу
const zonedDateTimeFromInstant = instant.toZonedDateTimeISO(timeZone); // Часовий пояс, наприклад 'America/Los_Angeles'
console.log(zonedDateTimeFromInstant.toString());
Конвертація між часовими поясами
Ви можете конвертувати `Temporal.ZonedDateTime` в інший часовий пояс за допомогою методу `withTimeZone`:
const newTimeZone = 'Europe/London';
const zonedDateTimeInLondon = zonedDateTime.withTimeZone(newTimeZone);
console.log(zonedDateTimeInLondon.toString()); // Вивід: 2024-10-27T18:30:00+01:00[Europe/London]
Робота зі зміщеннями часових поясів
Метод `getOffsetStringFor` об'єкта `Temporal.TimeZone` надає рядок зміщення для заданого `Temporal.Instant`:
const timeZoneObject = new Temporal.TimeZone(timeZone);
const offsetString = timeZoneObject.getOffsetStringFor(zonedDateTime.toInstant());
console.log(offsetString); // Вивід: -07:00 (Залежно від правил переходу на літній час)
Дуже важливо використовувати правильні ідентифікатори часових поясів IANA для точних обчислень. Ці ідентифікатори підтримуються та регулярно оновлюються, щоб відображати зміни у переході на літній час та межах часових поясів.
Тривалості
Об'єкт `Temporal.Duration` представляє проміжок часу. Його можна використовувати для додавання або віднімання від дат та часу.
Створення `Temporal.Duration`
Ви можете створити `Temporal.Duration` за допомогою конструктора, вказавши роки, місяці, дні, години, хвилини, секунди, мілісекунди, мікросекунди та наносекунди:
const duration = new Temporal.Duration(1, 2, 3, 4, 5, 6, 7, 8, 9); // Роки, Місяці, Дні, Години, Хвилини, Секунди, Мілісекунди, Мікросекунди, Наносекунди
console.log(duration.toString()); // Вивід: P1Y2M3DT4H5M6.007008009S
Або використовуючи рядок тривалості у форматі ISO 8601:
const durationFromString = Temporal.Duration.from('P1Y2M3DT4H5M6S');
console.log(durationFromString.toString()); // Вивід: P1Y2M3DT4H5M6S
Додавання тривалостей до дат та часу
const plainDate = new Temporal.PlainDate(2024, 10, 27);
const duration = new Temporal.Duration(0, 0, 7); // 7 днів
const newDate = plainDate.plus(duration);
console.log(newDate.toString()); // Вивід: 2024-11-03
Зауважте, що додавання тривалостей, які включають місяці або роки, до дат вимагає обережного підходу, оскільки кількість днів у місяці чи році може змінюватися.
Календарні системи
Temporal API підтримує різні календарні системи, крім григоріанського календаря. Це надзвичайно важливо для додатків, яким потрібно обробляти дати в різних культурних контекстах. Хоча підтримка все ще розвивається, вона створює основу для майбутнього розширення.
Використання альтернативних календарів
Щоб використати конкретний календар, ви можете вказати його при створенні об'єктів Temporal:
const hebrewDate = new Temporal.PlainDate(5785, 1, 1, { calendar: 'hebrew' });
console.log(hebrewDate.toString()); // Конкретний вивід може відрізнятися залежно від реалізації та форматування. На момент написання статті для багатьох середовищ потрібен поліфіл.
Важливо: Підтримка негригоріанських календарів може вимагати поліфілів або специфічної підтримки браузера/середовища. Перевіряйте документацію Temporal API та таблиці сумісності браузерів для отримання найновішої інформації.
Форматування дат та часу
Хоча Temporal API зосереджений на маніпуляціях з датою та часом, форматування зазвичай виконується за допомогою об'єкта `Intl.DateTimeFormat`, який є частиною Internationalization API. Об'єкти Temporal бездоганно працюють з `Intl.DateTimeFormat`.
Використання `Intl.DateTimeFormat`
Ось як відформатувати `Temporal.PlainDate` за допомогою `Intl.DateTimeFormat`:
const plainDate = new Temporal.PlainDate(2024, 10, 27);
const formatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatter.format(plainDate)); // Вивід: October 27, 2024
const formatterGerman = new Intl.DateTimeFormat('de-DE', { year: 'numeric', month: 'long', day: 'numeric' });
console.log(formatterGerman.format(plainDate)); // Вивід: 27. Oktober 2024
Ви можете налаштовувати параметри формату відповідно до ваших потреб. Першим аргументом `Intl.DateTimeFormat` є локаль, яка визначає мову та регіональні угоди, що використовуються для форматування. Використання різних локалей (наприклад, 'en-US', 'de-DE', 'fr-FR', 'ja-JP') дає різні формати виводу.
Форматування `Temporal.ZonedDateTime`
Форматування `Temporal.ZonedDateTime` є схожим, але ви також можете включити інформацію про часовий пояс у вивід:
const plainDateTime = new Temporal.PlainDateTime(2024, 10, 27, 10, 30, 0);
const timeZone = 'America/Los_Angeles';
const zonedDateTime = plainDateTime.toZonedDateTime(timeZone);
const formatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZoneName: 'short' });
console.log(formatter.format(zonedDateTime)); // Вивід: October 27, 2024, 10:30 AM PDT (Абревіатура часового поясу залежить від правил переходу на літній час)
Найкращі практики інтернаціоналізації
При роботі з датами та часом у глобальному контексті, пам'ятайте про наступні найкращі практики:
- Використовуйте ідентифікатори часових поясів IANA: Завжди використовуйте ідентифікатори часових поясів IANA (наприклад, `America/Los_Angeles`, `Europe/London`) для точної обробки часових поясів.
- Пам'ятайте про перехід на літній час: Перехід на літній час (DST) може впливати на зміщення часових поясів. Temporal API автоматично обробляє переходи DST.
- Використовуйте `Intl.DateTimeFormat` для форматування: Використовуйте об'єкт `Intl.DateTimeFormat` для форматування дат і часу відповідно до локалі користувача.
- Враховуйте календарні системи: Якщо ваш додаток повинен підтримувати користувачів у різних культурних контекстах, розгляньте можливість використання альтернативних календарних систем.
- Зберігайте дати та час в UTC: При зберіганні дат та часу в базі даних найкращою практикою є зберігання їх в UTC (Всесвітній координований час), щоб уникнути проблем із часовими поясами. Потім конвертуйте до місцевого часу для відображення. Temporal надає методи для конвертації до та з UTC.
- Ретельно тестуйте: Тестуйте ваш додаток з різними часовими поясами, локалями та календарними системами, щоб переконатися, що він працює коректно для всіх користувачів.
Порівняння Temporal API зі старим об'єктом Date
Ось таблиця, що висвітлює ключові відмінності та переваги Temporal API порівняно зі старим об'єктом `Date`:
Характеристика | Старий об'єкт `Date` | Temporal API |
---|---|---|
Мінливість | Мінливий (модифікує оригінальний об'єкт) | Незмінний (повертає нові об'єкти) |
Підтримка часових поясів | Обмежена та часто проблематична | Надійна та точна, на основі бази даних часових поясів IANA |
API | Непослідовний та складний у використанні | Чіткий, послідовний та інтуїтивно зрозумілий |
Точність | Мілісекундна | Наносекундна |
Календарні системи | Обмежена григоріанським | Підтримує альтернативні календарні системи (з підтримкою, що розвивається) |
Інтернаціоналізація | Вимагає зовнішніх бібліотек для надійної інтернаціоналізації | Вбудована підтримка та безшовна інтеграція з `Intl.DateTimeFormat` |
Підтримка браузерами та поліфіли
Оскільки це відносно новий API, підтримка Temporal API браузерами все ще розвивається. Перевіряйте останні таблиці сумісності браузерів (наприклад, на MDN Web Docs), щоб дізнатися, які браузери та середовища підтримують його нативно. Для старих браузерів або середовищ без нативної підтримки ви можете використовувати поліфіли для надання функціональності Temporal API. Шукайте "Temporal API polyfill" в Інтернеті, щоб знайти відповідні варіанти.
Висновок
JavaScript Temporal API є значним кроком вперед в обробці дат та часу в JavaScript. Його незмінність, чіткий API, надійна підтримка часових поясів та можливості календарних систем роблять його потужним інструментом для розробників, які створюють додатки, що потребують точної та надійної роботи з датами та часом у різноманітних міжнародних контекстах. Хоча підтримка браузерами все ще розвивається, переваги Temporal API роблять його вартим вивчення та впровадження в нових проєктах. Використовуючи Temporal API та дотримуючись найкращих практик інтернаціоналізації, ви можете створювати додатки, які забезпечують бездоганний та точний досвід роботи з датою та часом для користувачів по всьому світу.