Ці типи найчастіше «ламаються» на межі між системами - і помилки проявляються не одразу, а в окремих часових поясах, на певних сумах чи при великих ID.
Дата й час - мить у часі:
- формат RFC 3339 (профіль ISO 8601) з поясом:
2026-10-04T07:15:00Zчи2026-10-04T10:15:00+03:00; - сервер зберігає й віддає в UTC, а в місцевий час перетворює клієнт для показу;
- ніколи без поясу:
2026-10-04 10:15:00різні клієнти зрозуміють по-різному.
Дата без часу (день народження, дата події) - окремий тип "2026-10-04". Перетворення на мить у часі зсуне її на день у деяких поясах.
Локальний час із поясом користувача (зустріч о 10:00 за Києвом наступного вівторка) - зберігають локальний час + ідентифікатор поясу (Europe/Kyiv), а не зміщення: правила переходу на літній час змінюються, і +03:00 для майбутньої дати може стати неправильним.
Тривалість - ISO 8601 (PT15M) або явні одиниці в назві поля (duration_seconds).
Гроші:
- не
float:0.1 + 0.2- класика. JSON-число парсери перетворюють на double; - мінімальні одиниці цілим числом (
"amount": 125050- копійки) або рядок ("125.50"); - валюта завжди поруч (
"currency": "UAH", ISO 4217) - бо кількість знаків після коми різна (у японської єни - нуль); - округлення - на сервері, за явними правилами; клієнт не перераховує суми сам.
Великі ідентифікатори:
- JavaScript точно представляє цілі лише до 2^53 - 1.
BIGINTз бази, Snowflake-ID, ідентифікатори Twitter - рядком:"id": "1844712345678901234"; - для UUID - рядок у канонічному вигляді.
Числа з високою точністю (координати, курси, наукові дані) - рядок або явно задокументована точність.
Перелічення - рядки-коди ("status": "paid"), а не числа: порядок і значення не залежать від внутрішнього enum.
Що варто зафіксувати в документації API: формат кожного такого поля з прикладом. Помилки «в нас усе працює, у клієнта з Нью-Йорка - ні» майже завжди про недописаний формат дат.
У Laravel: касти datetime серіалізуються в ISO 8601 UTC; decimal:2 - рядком; для великих BIGINT у ресурсі - явне (string) $this->id.