Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

New DateTime Class

Two new classes have been added to better handle dates and times, the DateTimePlus class, which is a stand-alone component that adds missing functionality to the standard PHP DateTime class, and the DrupalDateTime class, which extends the DateTimePlus class to provide Drupal-specific handlers and features, including translation of formatted date values.

Drupal core and contributed modules should use the DrupalDateTime class in preference to the PHP DateTime class or to functions like date(), gmdate(), strtotime(), etc.

The new class has the ability to accept various kinds of input values to create a date object. That input could include a datetime string with an unknown format, a string with a known format (useful to remove ambiguity from things like international format preferences), an array of date parts (useful for form handling), a timestamp, or even another Date object.

The timezone input is also improved. You can pass in a DateTimeZone object or the name of a timezone. If no timezone name is specified, the value of drupal_get_user_timezone() will be used as the timezone (i.e. the user timezone preference, if any, otherwise the site timezone).

In addition, the class incorporates the IntlDateFormatter into its format() method, if the IntlDateFormatter is available, and otherwise falls back to wrapping formatted output with Drupal's translation system. The IntlDateFormatter requires additional information, which can be passed in a settings array.

Finally, the class tightens up the leniency of the created dates so we can more easily validate date input and adds methods to check if there are errors and retrieve any errors registered while creating the date. The base PHP class is very lenient about interpreting dates, too lenient if you want to do validation of date inputs. For instance, it will take a date like '2/31/2012' and instead of treating that as an invalid date, it will turn it into '3/2/2012'. Instead, we treat that as an error because the input date does not match the object that was created from it.

Usage examples

Note: Be sure to add "use Drupal\Core\Datetime\DrupalDateTime;" at the top of any files that use this class.

Create a date from a string and the name of a timezone. The timezone object will be created automatically for timezones passed to the constructor. The setTimezone() method is unchanged from the base class and still expects a DateTimeZone object.

$date = new DrupalDateTime('2012-12-31 12:30:00', 'UTC');
$date->setTimezone(new \DateTimeZone('America/Chicago'));
print $date->format('m/d/Y g:ia');

Create a date from an array of date parts and confirm that it is valid, then convert it to UTC for storage.

$date = DrupalDateTime::createFromArray( array('year' => 2012, 'month' => 12, 'day' => 31));
if ($date instanceOf DrupalDateTime && !$date->hasErrors()) {
  $date->setTimezone(new \DateTimeZone('UTC');
  $saved_value = $date->format('Y-m-d\TH:i:s');
}

Create a date and modify it using strtotime()-like phrases, then print the result. The name of the day will be translated using Drupal's translation system.

$date = new DrupalDateTime('next Tuesday at 10 AM');
$date->modify('+1 week');
print $date->format('l, F j, Y - H:i');

Create a date from a string and a format. The format makes it clear which is the month and which is the day in the input date.

$date = DrupalDateTime::createFromFormat('d.m.Y H:i:s', '07.03.2012 01:30:00');

Update:
Change notice: Optimize date formatting performance simplified the constructor and added static methods for creating date objects from a timestamp, array or fixed format due to performance issues and DX problems.

$date = DrupalDateTime::createFromDateTime($datetime);
$date = DrupalDateTime::createFromArray($array);
$date = DrupalDateTime::createFromTimestamp($timestamp);
$date = DrupalDateTime::createFromFormat($format, $time);
Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Not done

Comments

Mojtaba Reyhani’s picture

I try to use "DrupalDateTime" Class in my theme to show native date and time in custom format based on special TimeZone in nodes.
According to this article:

the class incorporates the IntlDateFormatter into its format() method, if the IntlDateFormatter is available, and otherwise falls back to wrapping formatted output with Drupal's translation system. The IntlDateFormatter requires additional information, which can be passed in a settings array.

And then I add below code to MyThmeName.theme:

if (isset($variables['node'])) {
  $date = DrupalDateTime::createFromTimestamp($variables['node']->getCreatedTime(), new \DateTimeZone('Asia/Tehran'), ['langcode' => 'fa']);
  $variables['date'] = $date->format('Y/m/d');
}

I'm sure intl Extension was exist! I cleared comment before this line in php.ini file:
;extension=php_intl.dll

I'm following all steps carefully but the result not changed and date is shown in english language yet and howsoever I try I can't get a appropriate result to show date and time in my native calendar, where is the problem, is there other parameters that should be set.
Thanks for any help.

colan’s picture

If you need access to the PHP DateTime class for whatever reason, see #2906229: Add DateTimePlus::getPhpDateTime() for situations that require a DateTimeInterface.