I suspect the problem has to do with some of the nuances of
strtotime() can take just about any string, and convert it into a Unix timestamp. The problem is that when the string doesn't contain an explicit timezone, it will use what is set by
date_default_timezone_get(). That should be set from the current user, though (it is set by the account proxy). However, the string that you are pulling out of
$node->field_date->value is implicitly in UTC. In other words, I think the string is being parsed by
strtotime() is being interpreted as in 'America/New_York' and not 'UTC'.
The good news is that you can simplify your situation a lot. The field item for a date range consists of four parts
- 'value' is the start date as a string in UTC
- 'start_date' is a DrupalDateTime object representing 'value'
- 'end_value' is the end date as a string in UTC
- 'end_date' is a DrupalDateTime object representing 'end_value'
For a plain date time field they are
- 'value' is the date as a string in UTC
- 'date' is a DrupalDateTime object representing 'value'
So, you can work with the
DrupalDateTime() object directly. In addition, that
date.formatter service should pull in the proper timezone in use by the user viewing the page by default (in addition to using the user's active language).
I suspect something like this will work
$node = Node::load(2100);
$start_date = $node->field_date->start_date;
$formatted = \Drupal::service('date.formatter')->format(
$start_date->getTimestamp(), 'custom', 'Y-m-d H:i:s P'
Note I added the 'P' format placeholder in there so you can see what what timezone the system thinks is in use.
Make sure you have the proper timezone set up on admin/config/regional/settings, and that your user timezone is what you are expecting. Also ensure that you have the proper timezone set in your php.ini (it's the
date.timezone setting); weird things happen when this isn't set (And off the top of my head, I don't recall if that causes a warning in the installer or on the status report when not set. I remember the issue, but not whether it got committed).