diff --git a/.changeset/date-field-preserve-non-midnight-instant.md b/.changeset/date-field-preserve-non-midnight-instant.md new file mode 100644 index 000000000..54064de1d --- /dev/null +++ b/.changeset/date-field-preserve-non-midnight-instant.md @@ -0,0 +1,5 @@ +--- +'@keystatic/core': patch +--- + +Avoid silently truncating non-midnight UTC `Date` values in `fields.date().parse()` (#1615). diff --git a/packages/keystatic/src/form/fields/date/date.test.ts b/packages/keystatic/src/form/fields/date/date.test.ts new file mode 100644 index 000000000..f99dc71d9 --- /dev/null +++ b/packages/keystatic/src/form/fields/date/date.test.ts @@ -0,0 +1,16 @@ +import { expect, test } from '@jest/globals'; +import { date } from './index'; + +test('parses UTC midnight Date instances into YYYY-MM-DD', () => { + const field = date({ label: 'Publish Date', validation: { isRequired: true } }); + const parsed = field.parse(new Date('2026-09-01T00:00:00.000Z')); + expect(parsed).toBe('2026-09-01'); + expect(field.validate(parsed)).toBe('2026-09-01'); +}); + +test('does not silently truncate Date instances carrying a non-zero UTC time (#1615)', () => { + const field = date({ label: 'Publish Date', validation: { isRequired: true } }); + const parsed = field.parse(new Date('2026-09-01T13:00:00.000Z')); + expect(parsed).toBe('2026-09-01T13:00:00.000Z'); + expect(() => field.validate(parsed)).toThrow('Publish Date is not a valid date'); +}); diff --git a/packages/keystatic/src/form/fields/date/index.tsx b/packages/keystatic/src/form/fields/date/index.tsx index a8224857e..996fffdfc 100644 --- a/packages/keystatic/src/form/fields/date/index.tsx +++ b/packages/keystatic/src/form/fields/date/index.tsx @@ -52,6 +52,14 @@ export function date({ return null; } if (value instanceof Date) { + if ( + value.getUTCHours() !== 0 || + value.getUTCMinutes() !== 0 || + value.getUTCSeconds() !== 0 || + value.getUTCMilliseconds() !== 0 + ) { + return value.toISOString(); + } const year = value.getUTCFullYear(); const month = String(value.getUTCMonth() + 1).padStart(2, '0'); const day = String(value.getUTCDate()).padStart(2, '0');