How to show a date in the correct timezone? I have a Datetime Range field (field_date) in a content type. Once I create my content type I set the Start Date as:

2017-02-27 19:30:01



Now I want to get the value and show the date in other format, so try to use the following code:

// Loading the node.
$node = Node::load(2100);
// Getting the start date value.
$date = $node-&gt;field_date-&gt;value;
// Printing to see what is the output.
dpm($node-&gt;field_date-&gt;value);
$date = strtotime($date);
// Printing my timezone.
dpm(drupal_get_user_timezone());
// Applying my custom format.
$date = \Drupal::service('date.formatter')-&gt;format($date, 'custom', 'Y-m-d H:i:s', drupal_get_user_timezone());
// Printing to see the output.
dpm($date);


This is my output:

// It's fine.
2017-02-28T00:30:01
// Its fine.
America/New_York
// This is not what I waiting for. I'm waiting here: 2017-02-27 19:30:01
2017-02-28 00:30:01


So, how to show a date in the correct timezone?
I suspect the problem has to do with some of the nuances of strtotime().

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-&gt;field_date-&gt;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-&gt;field_date-&gt;start_date;
$formatted = \Drupal::service('date.formatter')-&gt;format(
  $start_date-&gt;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).