Problem/Motivation

When in a UTC+13 timezone (like New Zealand during daylight savings time) tokens for date-only fields show incorrectly.

This may also apply to UTC+12 timezones although I have not tested those.

Steps to reproduce

  1. Set site timezone to New Zealand during daylight savings.
  2. Add a date-only field to a content type, e.g. field_issue_date
  3. Update the path alias pattern for that content type to use the field, e.g. [node:field_issue_date:date:html_date]/[node:title]
  4. Create a node and select the current date (2022-10-27) as the value of the date-only field. Save the node to create it.
  5. The date in the URL is set to tomorrow (/2022-10-28/node-title) while Drupal correctly renders the date field as today.

Why does this happen?

  • Drupal stores the date as 2022-10-27 in the database which is in UTC time (but the actual timezone is not relevant as the day is not a true date).
  • Token loads this and turns it into a PHP date object: 2022-10-27 12:00:00 UTC.
  • Token converts this object into the local timezone: 2022-10-28 01:00:00 NZDT.
  • Token renders values from the transformed timezone.

Proposed resolution

Token should always render date-only fields in UTC since they are not intended to be true date objects with timezones.

Issue fork token-3317688

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

dieuwe created an issue. See original summary.

ericgsmith made their first commit to this issue’s fork.

ericgsmith’s picture

Bitten by this bug today.

Good summary of the issue.

If we look at what core is doing it adds a check for the type when setting the timezone https://git.drupalcode.org/project/drupal/-/blob/11.2.8/core/modules/dat...

I believe around here https://git.drupalcode.org/project/token/-/blob/8.x-1.16/token.tokens.in... we should add a check for the type on the field definition - and if it is date we could add an additional timezone - perhaps as an additional option? I'm not familiar with the token module enough, but some way of passing this along to the generate method would be needed.

Then we should just need to use it here https://git.drupalcode.org/project/token/-/blob/8.x-1.16/token.tokens.in... instead of passing NULL as the timezone.

Will do a bit of hacking around see if I can get something working

ericgsmith’s picture

Cool - test added to show the issue fails as expected: https://git.drupalcode.org/issue/token-3317688/-/jobs/7344007#L263

ericgsmith’s picture

Status: Active » Needs review

Setting this to needs review although I'm really not sure if we should be passing timezone as an option or data - maybe a token expert can weigh in here.

Either way - I think this demonstrates the issue well and hopefully not too far away from a fix - happy to keep pushing this forward if somebody can please review.

Pipeline with test + fix passing: https://git.drupalcode.org/issue/token-3317688/-/jobs/7344220

Test only changes failing demonstrate the issue: https://git.drupalcode.org/issue/token-3317688/-/jobs/7344224

berdir’s picture

Status: Needs review » Needs work

Posted a review of how I think we can simplify this a bit.

ericgsmith’s picture

Thanks @berdir - replied on the MR

berdir’s picture

ericgsmith’s picture

Thanks @berdir - I've added a bit more explanation to what I'm seeing locally.

The commit you referenced does show that core supplies a timezone to the formatter, so I don't think we can get this to format correctly without passing the correct timezone somehow.

I'm not saying an additional option is the best way - if we passed the original datetime object around instead of a timestamp that would also give us the ability to provide the original timezone to the formatter, but I'm not sure how much refactoring / knock on effects that would have.