I am trying to programmatically load a node and get its date time value. The default format is HTML5 date, long date. I load it and I get the field value with the following code.

$entity = \Drupal\node\Entity\Node::load($record['nid_value']);

The output is the following one.


Why is it stored as 2018-02-23T02:00:00 when the real date is Thursday - February 22, 2018 - 4:00pm to 5:00pm?

The field type is date range; the display type is smart range. When you view the node, it looks perfect. The display is correct. If I create a view, it also outputs the incorrect date, no matter what format I chose on the field output. Time zone has been forced.

Looks correct on node display

Can anyone point me in the right direction here?

UPDATE - Here was the solution to my problem

$nid = 411;
$entity = \Drupal\node\Entity\Node::load($nid);
$dval = $entity->get('field_date_range')->value();
$dt = new DateTime($dval, new DateTimeZone('UTC'));
$dt->setTimezone(new DateTimeZone('America/Los_Angeles'));
$date_to_print = $dt->format('g:ia \o\n l jS F Y');
//$date_to_print = $dt->format('m-d-Y h:m:i');
echo $date_to_print;
//output: 12:00pm on Saturday 24th February 2018

2 Answers 2


Datetime and Daterange fields are stored in UTC in the database (the storage) and converted to the time zone on output. This is done because the system supports users across the world, so everything is normalized to UTC.

Basically, when you use the UI the field widget takes the input value, and converts it from the user's time zone per system configuration to UTC (see DateTimeWidgetBase::massageFormValues()). The actual format in storage is the ISO equivalent to the PHP format Y-m-d\TH:i:s.

When output, it takes loads the UTC value, and converts it to the user's time zone per system configuration or uses the forced time zone (the time zone override). See DateTimeDefaultFormatter::formatDate() for an example, and also DateFormatter::format().

By default, views output field values using the formatters, so the same rules apply.
It sounds like you may have an override in the view settings for the field.

  • Great info, although I used a different approach, this led me in the right direction. Feb 20, 2018 at 22:29

I solved the issue like that for type Time Range field.

I also using a custom format because the format is different for each language (translate format). /admin/config/regional/date-time

$from = \Drupal::service('date.formatter')->format($range['from'], 'custom_time_format', '', 'UTC');
$to = \Drupal::service('date.formatter')->format($range['to'], 'custom_time_format', '', 'UTC');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.