Date Field Serialization#
Strapi distinguishes between date, datetime, and timestamp field types. The date type stores only a calendar date and requires strict YYYY-MM-DD format on the wire — no time component, no timezone suffix. The datetime and timestamp types accept full ISO 8601 strings.
Backend: Parsing and Validation#
The canonical parsing logic lives in packages/core/database/src/fields/shared/parsers.ts.
-
parseDate— The authoritative handler fordatefields. It:-
Validates the input against
DATE_REGEX(/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/) . -
If the input contains a valid date prefix but also carries extra characters (e.g., a full ISO timestamp like
2024-12-07T00:00:00.000Z), it extracts the date portion viaPARTIAL_DATE_REGEXand emits aprocess.emitWarning:[deprecated] Using a date format other than YYYY-MM-DD will be removed in future versions. Date received: <value>. Date stored: <extracted>. -
If no extractable date prefix exists at all, it throws
InvalidDateError. -
Returns only the
YYYY-MM-DDportion — the time component is always discarded .
⚠️ A TODO comment at line 45 marks this graceful fallback for removal — it will be replaced by a hard
InvalidDateErrorin a future major version . Any integration that sends full ISO timestamps to adatefield will break when that change lands. -
-
parseDateTimeOrTimestamp— Used fordatetime/timestampfields; accepts full ISO strings and Unix millisecond timestamps viadate-fns.parseISOanddate-fns.parse.
Admin Frontend: Date Picker Component#
The Admin UI date picker is in packages/core/admin/admin/src/components/FormInputs/Date.tsx.
Key behavior :
- On each date selection, the picker converts the local
Dateobject to UTC midnight viatoUTCMidnight, then serializes withutcDate.toISOString().split('T')[0]— stripping the time component before dispatchingfield.onChange. - On blur with an invalid partial input, the field reverts to the last known valid value using the same
split('T')[0]pattern . maxDateis capped at2099-12-31.
Why this matters: Before PR #25372, the picker was sending utcDate.toISOString() (e.g., 2024-12-07T00:00:00.000Z). This triggered the backend deprecation warning on every save, and would have caused hard failures once the TODO-marked error is enabled .
Format Summary#
| Field type | Expected wire format | Parser function |
|---|---|---|
date | YYYY-MM-DD | parseDate |
datetime | ISO 8601 / Unix ms | parseDateTimeOrTimestamp |
timestamp | ISO 8601 / Unix ms | parseDateTimeOrTimestamp |
Common Failure Modes#
- Sending a full ISO string to a
datefield (e.g., from a custom integration or older Admin version): triggers the[deprecated]process.emitWarningtoday; will throwInvalidDateErrorin future versions. - Timezone drift:
toUTCMidnightanchors dates to UTC midnight so local-time offsets don't shift the stored date by one day. Any code outside the Admin UI that constructs date strings should apply the same UTC normalization before slicing off the time portion. - Invalid or unparseable values (no date prefix at all): immediately throw
InvalidDateError— no fallback or warning .
Key Source Files#
| File | Purpose |
|---|---|
packages/core/database/src/fields/shared/parsers.ts | Backend date/datetime/time parsers; DATE_REGEX, deprecation warning, InvalidDateError |
packages/core/admin/admin/src/components/FormInputs/Date.tsx | Admin UI date picker; UTC-midnight conversion, YYYY-MM-DD serialization |
| PR #25372 | Fix that aligned the Admin date picker output with the backend's format requirement |