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 usage:
$node = $this->entityTypeManager
->getStorage('node')
->create([
'type' => 'article',
'title' => 'test',
]);
// Get the default timezone
$default_timezone = new \DateTimeZone(date_default_timezone_get());
// Set some date/time objects
$now = new \DateTime('now', $default_timezone);
$yesterday = new \DateTime('yesterday', $default_timezone);
// Compare the dates
if($yesterday < $now){
// Do some stuff
}
// Optionally convert to DrupalDateTime if you need the custom methods, etc
$now = DrupalDateTime::createFromDateTime($now);
$yesterday = DrupalDateTime::createFromDateTime($yesterday);
// Get the storage timezone
$storage_timezone = new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE);
// Save the dates to the fields
$node->set(
'field_date_now',
$now
->setTimezone($storage_timezone)
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)
);
$node->set(
'field_date_yesterday',
$yesterday
->setTimezone($storage_timezone)
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT)
);
$node->save();
A bonus example — find nodes with a date/time field value that matches a 24hr window:
$date = new \DateTimeImmutable('now - 1 month', new \DateTimeZone(date_default_timezone_get()));
$start_time = $date->modify('midnight');
$start_time = DrupalDateTime::createFromDateTime($start_time);
$end_time = $date->modify('+1 day midnight -1 second');
$end_time = DrupalDateTime::createFromDateTime($end_time);
// Find all NODES with date times that match the 24hr window
$query = \Drupal::entityQuery('node')
// ->condition('status', 1)
->condition('type', 'event')
->condition(
'field_date',
$start_time
->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),
'>='
)
->condition(
'field_date',
$end_time
->setTimezone(new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE))
->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT),
'<='
)