I couldn’t find any similar issues on Drupal.org so I opened this one, if anyone knows of a similar issue please feel free to link and close this as duplicate.
Problem/Motivation
This was found while diagnosing an issue on the Scheduler module. However it also affects the “Authored On” field.
https://www.drupal.org/project/scheduler/issues/3085947
The node edit form's "Authored On" field uses the timezone of whatever user was on that form during the last cache clear. This can end up with a Chicago User saving a node that has an “Authored On” value in UTC.
This only seems to affect new nodes, editing existing nodes are not affected.
Steps to Reproduce
Requirements: Have two users, one with a UTC timezone and one with a Chicago Timezone
Step One: Create content as an UTC User
- Log in as the UTC user
- Clear the Drupal cache
- Create a new Basic Page
- Note the Authoring information (e.g 4:00:00 PM)
- Save and publish the node.
Step Two: Create content as a Chicago User
- Log in as the Chicago user
- Do not clear the cache
- Create a new Basic Page
- Note the Authoring information
- Observe that the Authoring information shows approximately the same time at UTC (e.g 4:02 PM)
- This should show a time relative to Chicago (e.g 11:00 AM)
For authoring information this is relatively benign however it does impact Scheduling.
Proposed resolution
It looks like this is being caused by code in the Datetime::getInfo() method.
core/lib/Drupal/Core/Datetime/Element/Datetime.php
public function getInfo() {
// .. node: some code removed for brevity …
return [
'#input' => TRUE,
'#element_validate' => [
[$class, 'validateDatetime'],
],
'#process' => [
[$class, 'processDatetime'],
[$class, 'processAjaxForm'],
[$class, 'processGroup'],
],
'#pre_render' => [
[$class, 'preRenderGroup'],
],
'#theme' => 'datetime_form',
'#theme_wrappers' => ['datetime_wrapper'],
'#date_date_format' => $date_format,
'#date_date_element' => 'date',
'#date_date_callbacks' => [],
'#date_time_format' => $time_format,
'#date_time_element' => 'time',
'#date_time_callbacks' => [],
'#date_year_range' => '1900:2050',
'#date_increment' => 1,
// Timezone is set here and gets cached.
'#date_timezone' => drupal_get_user_timezone(),
];
}
The getInfo() method only gets called on cache clear, therefore the element that gets loaded gets the timezone of whichever user loads the page after the cache is cleared.
This bug has seemingly been in place for some time, but it was made much more visible with the deprecation of drupal_get_user_timezone()
in #2799987: Datetime and Datelist element's timezone handling is fragile, buggy and wrongly documented. Prior to that the site's timezone would be used rather than the server's timezone when caches are built without a user (eg, via drush, or some other backend process.)