JSON Toolkit

Який формат для часових міток у JSON

Головне: Epoch-числа й рядки ISO мають власні компроміси, але ламає речі саме їх змішування. Використовуйте ISO 8601 зі зміщенням, зберігайте UTC, відображайте в часовому поясі користувача.

Початковий~3 хв читанняОпубліковано 2026-10-30Оновлено 2026-10-30
Вибір формату часової мітки для JSON API

Коротко: використовуйте ISO 8601 з явним зміщенням у мережі, зберігайте UTC із завершальним Z і конвертуйте лише під час показу; якщо обираєте epoch-числа, глобально фіксуйте секунди проти мілісекунд і кладіть одиницю в назву поля.

Чому 2026-10-30 14:30:00 недостатньо

Цей рядок не несе поясу. 14:30 у Шанхаї й 14:30 у Лондоні різняться на вісім годин, і немає способу сказати, який мається на увазі. new Date('2026-10-30 14:30:00') розбирається в локальному поясі середовища виконання, тож сервер і браузер виводять два різні моменти з одного навантаження — баг, що ніколи не відтворюється.

Гола 2026-10-30 взагалі не є моментом. Добре для днів народження й розрахункових періодів, неправильно для часу створення.

Два робочі формати

Рядки ISO 8601

{
  "createdAt": "2026-10-30T14:30:00+08:00",
  "updatedAt": "2026-10-30T06:30:00Z"
}

Читабельні, сортовані за узгодженого формату, з точністю до мілісекунд за потреби й самодостатні.

Epoch-числа

{ "createdAt": 1793519400 }

Компактні й однозначні, але нечитабельні, і секунди проти мілісекунд — постійна небезпека. Якщо обираєте epoch, стандартизуйте одиницю й кладіть її в назву поля: createdAtMs набагато безпечніше за createdAt.

Конвенції, варті раннього закріплення

Пункт Конвенція
Формат у мережі ISO 8601 з Z або +08:00
Пояс зберігання UTC, щоб літній час ніколи не входив у картину
Точність Мілісекунд достатньо
Найменування полів createdAt, updatedAt, expiresAt
Чисті дати Окреме поле date, наприклад birthday: "1990-01-01"
Тривалості Ціле плюс одиниця, наприклад timeoutMs: 3000

Відображення

new Intl.DateTimeFormat('en-GB', {
  dateStyle: 'medium',
  timeStyle: 'short',
  timeZone: 'Europe/London',
}).format(new Date('2026-10-30T06:30:00Z'));

Вказуйте timeZone явно, коли показ не повинен слідувати за пристроєм. Покладання на типове значення браузера правильне для часу для користувача й неправильне для звітів.

Три повторювані баги

Голі дати розбираються як опівночі UTC. За специфікацією ECMAScript рядки лише з датою є UTC, тоді як рядки дати-часу є локальними. Ця неузгодженість — надійне джерело багів на один день.

Пояс бази даних розходиться з серіалізатором. datetime у MySQL не має поясу; пишіть локально, читайте як UTC — і все зсувається на зміщення.

Літній час. Збереження майбутніх локальних часів створює моменти, що не існують або трапляються двічі. В UTC таких прогалин немає.

Часті питання

Як обирати між ISO 8601 і epoch-числами?

Використовуйте ISO 8601, коли люди читають навантаження, коли хочете лексикографічний порядок сортування або коли значення має нести власний пояс; ціна — приблизно десяток зайвих байтів і бібліотека розбору. Використовуйте epoch-числа, коли компактність і тривіальна міжмовна обробка важливіші, але глобально фіксуйте секунди проти мілісекунд і кажіть, яку одиницю містить поле.

Чи мають гола дата й часова мітка використовувати те саме поле?

Ні. Гола 2026-10-30 — це календарний день без часу й без поясу, тоді як поле часової мітки має нести точний момент. Тримайте дні народження й розрахункові періоди в окремому полі date, а для часу створення чи оновлення використовуйте поле ISO 8601 At.

Додаткове читання