Skip to content

[6.x] Format dates in generated fields in the site’s locale - #20467

Open
brandonkelly wants to merge 2 commits into
6.xfrom
bugfix/generated-field-dates
Open

brandonkelly wants to merge 2 commits into
6.xfrom
bugfix/generated-field-dates

Conversation

@brandonkelly

Copy link
Copy Markdown
Member

Description

Generated field templates printed dates however PHP stringified them, so cards showed raw values:

Template Before After (en-US site)
{startDate} (Date field, loaded from the DB) 2026-10-09 10:00:00 10/9/2026, 10:00 AM PDT
{startDate} (Date field set from code as a DateTime) save throws Object of class DateTime could not be converted to string 10/9/2026, 10:00 AM PDT
{postDate} 2026-03-04T13:06:00+00:00 3/4/2026, 5:06 AM
{startDate|date('Y')} 2026 2026

Generated field values are stored when an element is saved and differ by site, so they’re now formatted in the element’s site language, the same way entry title formats are rendered.

 ElementWrites::completeGeneratedFields()
   foreach site element
     foreach generated field
-      renderObjectTemplate(template, element)
+      I18N::withLocale(site language)
+        renderObjectTemplate(template, element, generatedFieldDateVariables(element, template))

generatedFieldDateVariables() passes each date attribute or custom field that the template references as a Carbon copy whose string form matches the date’s card preview:

  • custom fields use their own getPreviewHtml(), so date-only fields print only the date and time zones show the way they do in cards
  • native date attributes such as postDate use the formatter’s short date and time

Object template variables take precedence over the element’s own values for {foo} shorthand. Filters such as |date still receive a date. Full Twig like {{ object.startDate }} still prints the element’s own value.

Stored values change the next time their elements are saved. Run php artisan craft:resave:all to update existing values.

Evidence

  • Before: SaveElementTest › “formats dates that generated fields print in the site’s locale” fails on 6.x: Object of class DateTime could not be converted to string.
    After: It passes. A de site with the template {startDate} | {day} | {postDate} | {startDate|date("Y")} | [{endDate}] stores 09.10.2026, 10:00 PDT | 28.02.2027 | 04.03.2026, 05:06 | 2026 | [].
  • composer ci: Pint, Rector, PHPStan, and the core suite pass (12,425 tests). tests-adapter has 3 failures (Legacy\ConfigCompatibilityTest, Legacy\Markdown\LegacyMarkdownTest) that also fail on unchanged 6.x and pass when run alone.

brandonkelly and others added 2 commits November 7, 2026 22:18
Generated field templates printed dates with PHP’s default string
conversion: Carbon values as Y-m-d H:i:s, native date attributes as
ISO 8601, and plain DateTime values threw an error. Dates referenced by
a generated field template now print the way element cards show them,
in the element’s site language, while filters still get a date.

Amp-Thread-ID: https://ampcode.com/threads/T-01a1b7ff-b71a-7140-bea4-22eb1d71ca29
Co-authored-by: Amp <amp@ampcode.com>
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

📚 Storybook previews

@craftcms/ui — open Storybook

No changed components detected in this Storybook.

resources/js — open Storybook

No changed components detected in this Storybook.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant