17

I have a standard Drupal date field 'My date' (field_my_date). I can get its value:

$node->field_my_date->value  // returns: "2017-12-14T08:00:00"

But I want to get a formatted date string, which should look like: "14.12.2017".

If I analyse the field in the interactive shell (drush core-cli), then I see, that I can get the DateTimeFieldItemList object or DateTimeItem object:

>>> $node->field_my_date
=> Drupal\datetime\Plugin\Field\FieldType\DateTimeFieldItemList {#8836
 0: Drupal\datetime\Plugin\Field\FieldType\DateTimeItem {#8841},
}

>>> $node->field_my_date[0]
=> Drupal\datetime\Plugin\Field\FieldType\DateTimeItem {#8841
 value: [
   "value" => "2017-12-14T08:00:00",
 ],
}

But I have not found any method to reformat the date string. Is there some possibility to define the format of the output date string? Or do I have to reformat the output string e.g. like this:

date("j.n.Y", strtotime($node->field_my_date->value));
2
  • Where do you need this formatted string? Where is it going to be used/displayed?
    – mpdonadio
    Dec 18, 2017 at 15:13
  • In my custom module I need to get all dates from selected nodes. The dates (and other data) will be then used to create an e-mail message. Dec 18, 2017 at 15:19

3 Answers 3

45

A date field has two properties, value to store the date in UTC and date, a computed field returning a DrupalDateTime object, on which you can use the methods getTimestamp() or format():

// get unix timestamp
$timestamp = $node->field_date->date->getTimestamp();
// get a formatted date
$date_formatted = $node->field_date->date->format('Y-m-d H:i:s');

For a date range field:

// formatted start date
$start_date_formatted = $node->field_date->start_date->format('Y-m-d H:i:s');
// formatted end date
$end_date_formatted = $node->field_date->end_date->format('Y-m-d H:i:s');
8
  • 1
    This was essentially going to be my answer, but it is best to use the date.formatter service to handle any localization concerns, and to also allow the date format config entities to be used (instead of hardcoding format strings).
    – mpdonadio
    Dec 18, 2017 at 17:31
  • I tested it and it works perfectly. I do not understand, why the date property is not listed in the docs: api.drupal.org/api/drupal/… Dec 19, 2017 at 7:55
  • In case of complex field types (which have not the usual value property) I always look in the property definition, see DateTimeItem::propertyDefinitions
    – 4uk4
    Dec 19, 2017 at 8:00
  • I have a few similar problems. And I have found, that it is possible to get e.g. the name of a taxonomy term like this: $node->field_region->entity->name->value But I have no idea, where are all these properties listed. Or do I have to just use a trial and error approach? Dec 19, 2017 at 8:35
  • 1
    @Baud $item->date in a loop foreach ($node->field_date as $item)
    – 4uk4
    Jun 6, 2021 at 9:41
6

The Accepted answer is good, but for anybody that would like to use the New DrupalDateTime here are few examples.

I. If you have a date and want format it, just pass it to the static method of the class (DrupalDateTime) as follows. You can replace the string with your date variables. Below shows both using the static version and non static version of DrupalDateTime

 $date = DrupalDateTime::createFromFormat('j-M-Y', '20-Jul-2019');
// Using the static method prints out: 20-Jul-2019:11:am

$date = new DrupalDateTime('now');  // grab current dateTime using NON static
$date->format('l, F j, Y - H:i'); // format it 
// prints out nicely formatted version: Tue, Jul 16, 2019 - 11:34:am
// you can remove H:i and what's after it if you don't want hours or am pm

$date = new DrupalDateTime('now');  // grab current dateTime
// Or print $date->format('d-m-Y: H:i A');
// prints out: 16-07-2019: 11:43 AM

More examples:

$date = new DrupalDateTime();
$date->setTimezone(new \DateTimeZone('America/Chicago'));
print $date->format('m/d/Y g:i a');
// The above prints current time for given Timezone
// prints : 07/16/2019 10:59 am

// Another variations of the above except it takes specific date and UTC zone
$date = new DrupalDateTime('2019-07-31 11:30:00', 'UTC');
$date->setTimezone(new \DateTimeZone('America/Chicago'));
print $date->format('m/d/Y g:i a');
// prints 07/31/2019 6:30 am

To use these in your module/code you need to include the following at the top of your file;

 use Drupal\Core\Datetime\DrupalDateTime;

How to test it with Drush Save the above code in a php script let drush run the srcipt after it bootstraps drupal like:

drush -r /path-to-your-drupal-documentRoot -l example.com scr ~/path-to your-script

For multisites make sure you use http://example.com with the drush -l version

1

To avoid the next Y2K type problem (Unix timestamp fields running out of byte ), the dates are stored in SQL's date fields. The entity object is going to have the same value as is returned from the storage media (SQL).

When you display this using the standard render code, the display widget will handle the formatting. You can set this in the Entity Display form.

If you are doing this in your code, you will need to provide the formatting code yourself. It's not hard using the DateTime object with code similar to.

$new_datetime = DateTime::createFromFormat ( "Y-m-d\TH:i:sT", $row["timestamp"] );
$formatted_date $new_datetime->format('j.n.Y');

There's probably a way to do this in twig, but it would be much easier in a template preprocess hook.

6
  • Do I understand it correctly, that there is no way to get the reformatted string directly from the DateTimeItem object? Something like: $node->field_my_date[0]->format('j.n.Y') Dec 18, 2017 at 15:43
  • I expect, that my question is a little stupid, but I have expected, when the name of the class is DateTimeItem, that it will be possible to use it similarly as the class DateTime. Dec 18, 2017 at 15:46
  • 1
    It's a case of keeping the MVC design clean. The DateTimeItem is the data model and not related to the view (formatting). Confusion in naming is because SQL uses DateTime as the column type and so the Data Model uses that. In Drupal the formatting comes at render time which is done by field widgets. There is probably a way to run the field thru the defined widget to get the proper format.. but it would be more convoluted than just using PhP DateTime methods.
    – CG Monroe
    Dec 18, 2017 at 16:14
  • @CGMonroe datetime fields are stored as strings, and don't use the database specific column types. Unfortunately, those aren't portable between backends, which make things more complicated.
    – mpdonadio
    Dec 18, 2017 at 17:33
  • How do I use this with format_date('custom_format') twig function?
    – mevsme
    Mar 15, 2022 at 16:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.