diff --git a/raw/fields__date.md b/raw/_processed/fields__date.md similarity index 100% rename from raw/fields__date.md rename to raw/_processed/fields__date.md diff --git a/wiki/_master-index.md b/wiki/_master-index.md index e9906a4..af20eab 100644 --- a/wiki/_master-index.md +++ b/wiki/_master-index.md @@ -35,7 +35,7 @@ This 3-hop pattern works for hundreds of articles without vector search. | [[wiki/reports/_index\|reports/]] | Weekly and monthly summaries — generate: `uv run python scripts/report-generator.py --weekly` | 1 | | [[wiki/infrastructure/_index\|infrastructure/]] | Server inventory: all 10 SSH hosts — optical, optical-dev, optical-prod, baic, librechat, modocmms, box-cli, aimpress, pve | 12 | | [[wiki/testing/_index\|testing/]] | Web app testing: functional, performance, security, UI types; TDD/BDD/Agile methodologies; Selenium/Cypress/Playwright/JMeter/OWASP ZAP tools | 1 | -| [[wiki/payloadcms/_index\|payloadcms/]] | Full Payload CMS reference — getting started, config, database (Postgres/MongoDB/SQLite), all 22 field types, access control, hooks, authentication (cookies, JWT, API keys, custom strategies, token data), admin UI, custom components, Lexical rich text, live preview, versions/drafts, Local/REST/GraphQL APIs, queries, plugins, jobs queue, upload, ecommerce, production deploy, TypeScript, migration guides, i18n, localization | 67 | +| [[wiki/payloadcms/_index\|payloadcms/]] | Full Payload CMS reference — getting started, config, database (Postgres/MongoDB/SQLite), all 22 field types, access control, hooks, authentication (cookies, JWT, API keys, custom strategies, token data), admin UI, custom components, Lexical rich text, live preview, versions/drafts, Local/REST/GraphQL APIs, queries, plugins, jobs queue, upload, ecommerce, production deploy, TypeScript, migration guides, i18n, localization | 68 | | [[wiki/shared-patterns/_index\|shared-patterns/]] | Oliver Agency standard library patterns: httpx, structlog, pydantic-settings, alembic — reuse before writing from scratch | 4 | | [[wiki/mistakes/_index\|mistakes/]] | Anti-patterns extracted from sessions — per-stack running lists (fastapi, react, docker, postgres, general) — injected at session start | 5 | diff --git a/wiki/payloadcms/_index.md b/wiki/payloadcms/_index.md index ab0304a..753e526 100644 --- a/wiki/payloadcms/_index.md +++ b/wiki/payloadcms/_index.md @@ -68,3 +68,4 @@ | [[wiki/payloadcms/fields-checkbox\|Checkbox Field]] | Boolean field — config options, defaultValue, index, saveToJWT, hidden, virtual, custom components | raw/fields__checkbox.md | 2026-05-15 | | [[wiki/payloadcms/fields-code\|Code Field]] | Monaco editor UI (VS Code engine) storing a plain string — language syntax highlighting, editorOptions, custom components | raw/fields__code.md | 2026-05-15 | | [[wiki/payloadcms/fields-collapsible\|Collapsible Field]] | Presentational-only layout field — groups nested fields under a collapsible header; no DB column; supports dynamic label via `({ data, path })` | raw/fields__collapsible.md | 2026-05-15 | +| [[wiki/payloadcms/fields-date\|Date Field]] | Date picker field — ISO 8601 storage, pickerAppearance modes, timezone support with separate `_tz` column, custom UTC offsets, GraphQL enum names | raw/fields__date.md | 2026-05-15 | diff --git a/wiki/payloadcms/fields-date.md b/wiki/payloadcms/fields-date.md new file mode 100644 index 0000000..9473823 --- /dev/null +++ b/wiki/payloadcms/fields-date.md @@ -0,0 +1,180 @@ +--- +title: "Date Field" +aliases: [payload-date-field, date-field, datetime-field] +tags: [payloadcms, fields, date, timezone, react-datepicker] +sources: [raw/fields__date.md] +created: 2026-05-15 +updated: 2026-05-15 +--- + +## Overview + +The Date field saves a `Date` value in the database and renders a `react-datepicker` UI in the Admin Panel. Storage format is always ISO 8601: `YYYY-MM-DDTHH:mm:ss.SSSZ`. + +```ts +import type { Field } from 'payload' + +export const MyDateField: Field = { + name: 'publishedAt', + type: 'date', +} +``` + +## Config Options + +| Option | Description | +|--------|-------------| +| `name` * | DB property name | +| `label` | Admin Panel label (string or i18n object) | +| `index` | Build DB index for fast queries | +| `validate` | Custom validation (runs on both client + server) | +| `saveToJWT` | Include in JWT if top-level on auth collection | +| `hooks` | Field lifecycle hooks | +| `access` | Field-level access control | +| `hidden` | Hide from all APIs + Admin Panel (still saved to DB) | +| `defaultValue` | Default date value | +| `localized` | Enable per-locale date values | +| `required` | Make field required | +| `timezone` | Enable timezone picker (`true` or config object) | +| `virtual` | Disable DB column (`true`) or link to relationship | + +## Admin Options + +Nested under `admin.date`: + +| Property | Description | +|----------|-------------| +| `placeholder` | Input placeholder text | +| `displayFormat` | Format in list-view cells (unicode date format via `date-fns`) | +| `pickerAppearance` | `dayAndTime` \| `timeOnly` \| `dayOnly` \| `monthOnly` (default: `dayOnly`) | +| `monthsToShow` | 1 or 2 months in datepicker | +| `minDate` / `maxDate` | Restrict selectable date range | +| `minTime` / `maxTime` | Restrict selectable time range | +| `timeIntervals` | Minutes between time options (default: 30) | +| `timeFormat` | Time display format (default: `'h:mm aa'`) | +| `overrides` | Pass any prop directly to `react-datepicker` | + +### Display Format vs Picker Appearance + +- `displayFormat` affects only the **cell** in list view — takes any [unicode date format](https://date-fns.org/v4.1.0/docs/format) +- `pickerAppearance` controls the **datepicker widget** — when set alone, cell format auto-matches +- Stored value is always full ISO 8601 regardless of display settings + +## Example: Multiple Appearance Modes + +```ts +fields: [ + { + name: 'dateOnly', + type: 'date', + admin: { date: { pickerAppearance: 'dayOnly', displayFormat: 'd MMM yyy' } }, + }, + { + name: 'timeOnly', + type: 'date', + admin: { date: { pickerAppearance: 'timeOnly', displayFormat: 'h:mm:ss a' } }, + }, + { + name: 'monthOnly', + type: 'date', + admin: { date: { pickerAppearance: 'monthOnly', displayFormat: 'MMMM yyyy' } }, + }, +] +``` + +## Timezones + +Enable with `timezone: true` — adds a dropdown to the datepicker. The selected timezone is stored in a separate column `_tz`. + +```ts +{ + name: 'publishedAt', + type: 'date', + timezone: { + defaultTimezone: 'America/New_York', + supportedTimezones: [ + { label: 'New York', value: 'America/New_York' }, + { label: 'London', value: 'Europe/London' }, + ], + }, +} +``` + +| Timezone Option | Description | +|-----------------|-------------| +| `defaultTimezone` | Pre-selected timezone | +| `supportedTimezones` | Array of `{ label, value }` | +| `required` | Require timezone even if date is optional | +| `override` | Function to customize the auto-generated select field | + +**Important:** The date itself is stored in UTC. Your frontend is responsible for converting to the user's timezone. Dates without a time are normalised to 12:00 in the selected timezone. + +### Custom UTC Offsets + +Use `±HH:mm` format alongside IANA names: + +```ts +supportedTimezones: [ + { label: 'UTC+5:30 (India)', value: '+05:30' }, + { label: 'New York', value: 'America/New_York' }, +] +``` + +> UTC offsets are **fixed** — no DST handling. Use IANA names for DST awareness. + +### Timezone Override Function + +```ts +timezone: { + override: ({ baseField }) => ({ + ...baseField, + admin: { ...baseField.admin, disabled: { column: true } }, + }), +} +``` + +### GraphQL Enum Names for UTC Offsets + +| Offset | GraphQL Enum | +|--------|-------------| +| `+05:30` | `_TZOFFSET_PLUS_05_30` | +| `-08:00` | `_TZOFFSET_MINUS_08_00` | +| `+00:00` | `_TZOFFSET_PLUS_00_00` | + +IANA names are also transformed (e.g. `America/New_York` → `America_New_York`). REST API returns the raw value. + +## Custom Components + +Use `DateTimeField` from `@payloadcms/ui` for both server and client component slots: + +```tsx +// Server +import { DateTimeField } from '@payloadcms/ui' +import type { DateFieldServerComponent } from 'payload' + +export const CustomDateFieldServer: DateFieldServerComponent = ({ + clientField, path, schemaPath, permissions, +}) => +``` + +## Key Takeaways + +- Storage is always ISO 8601 UTC — display format only affects Admin Panel UI +- `pickerAppearance` drives what parts of the date are selectable (`dayOnly`, `timeOnly`, `dayAndTime`, `monthOnly`) +- Timezone support requires `timezone: true` — creates a separate `_tz` DB column +- Dates stored UTC; frontend must handle conversion for display +- UTC offset values (`+05:30`) don't handle DST — prefer IANA names for production use +- `displayFormat` uses `date-fns` unicode format strings +- `admin.date.overrides` lets you pass any prop directly to `react-datepicker` + +## Related + +- [[wiki/payloadcms/fields-basic|Fields: Basic]] — overview of all scalar field types +- [[wiki/payloadcms/fields-checkbox|Checkbox Field]] — another scalar field example +- [[wiki/payloadcms/database-indexes|Database Indexes]] — add `index: true` for date queries +- [[wiki/payloadcms/localization|Localization]] — using `localized: true` on date fields +- [[wiki/payloadcms/authentication-token-data|Token Data (saveToJWT)]] — embed date in JWT + +## Sources + +- `raw/fields__date.md` — https://payloadcms.com/docs/fields/date