Since Drupal 8.5.x this works a little differently.
Firstly it's good practice to set the timezone explicitly so you know what is going on:
Set the timezone:
$timezone = new \DateTimeZone('UTC');
// Or
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or
$timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);
Then create the date object using the PHP DateTime class:
$date_time = new \DateTime('now', $timezone);
$drupal_date_time = DrupalDateTime::createFromDateTime($date_time);
Or the DrupalDateTime class:
$drupal_date_time = new DrupalDateTime('yesterday', $timezone);
I like to use DateTime
(or DateTimeImmutable
) and then pass into the DrupalDateTime
wrapper. That way native methods are highlighted in the IDE and also date comparisons (e.g. $now > $somedatetime
work reliably.
Prior to saving the date/time you must set the timezone to DateTimeItemInterface::STORAGE_TIMEZONE
:
$drupal_date_time->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
You can then format the date for storage using the the DateTimeItemInterface::DATETIME_STORAGE_FORMAT constant:
$drupal_date_time->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)
Here is an example based on above use case:
$datetime_string = "2016-08-01 12:30:00";
// Get the default timezone
$timezone = new \DateTimeZone(date_default_timezone_get());
// Or set the timezone explicitly to match the $datetime_string
$timezone = new \DateTimeZone('Europe/London');
// Create the DateTime object
$datetime = new \DateTime($datetime_string, $timezone);
// Optionally convert to DrupalDateTime if you need the custom methods, etc
$datetime = DrupalDateTime::createFromDateTime($datetime);
// Create and save the node
$node = Node::create([
'type' => 'appointment'
'title' => $data['title'],
'body' => $data['body'],
'field_client' => $uid,
'field_appointment_date_time' => $datetime
->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),
]);
$node->save();