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

In Drupal 7:

We persisted date format patterns and types in the database. This approach served well to provide us the flexibility we need to translate date formats and handle many use cases. If you wanted to produce an array of formatted dates you would do this:

    $date_types = system_get_date_types();
    foreach ($date_types as $key => $value) {
      $date_formats[$value['type']] = check_plain(t($value['title'] . ' format')) . ': ' . format_date(REQUEST_TIME, $value['type']);
    }

In Drupal 8:

We can achieve the same level of flexibility by using the configuration entity system. To produce an array of formatted dates in Drupal 8 you would do this:

use Drupal\Component\Utility\String;
use Drupal\Core\Datetime\Entity\DateFormat;   
$date_types = DateFormat::loadMultiple();
$date_formatter = \Drupal::service('date.formatter');
foreach ($date_types as $machine_name => $format) {
  $date_formats[$machine_name] = t('@name format', array('@name' => $format->label)) . ': ' .$date_formatter->format(REQUEST_TIME, $machine_name);
}

The structure of an individual date format now looks like this (example from core.date_format.long.yml):

id: long
label: 'Default long date'
status: true
langcode: en
locked: false
pattern: 'l, F j, Y - H:i'

Where:

  • "id" refers to the date format's machine name
  • "uuid" is a unique identifier for this configuration entity
  • "label" contains the human readable name of the date format
  • "locked" if set to true hides the date format from the administrative page that allows users to modify the date format. When using a standard Drupal installation this is only set for "HTML Datetime", "HTML Date", "HTML Time", "HTML Yearless Date", "HTML Week", "HTML Month", and "HTML Year" date formats. "Default long date", "Default medium date", and "Default short date" are the only date formats that are initially editable to site administrators.
  • "pattern" contains the native php version of the date format pattern that is eventually sent to the date_format function

As a result of the simplicity gained from this approach we have no more need of persisting date type information separately and all functions relating to date types have been removed. Also we no longer need to persist this config within the database and therefore improves the portability of this configuration.

Note:
It is also enough to call drupal_get_user_timezone() to get the current timezone. Previously it was necessary to investigate whether the user can set the timezone and fall back to the site default timezone, now this all is handled inside drupal_get_user_timezone().

These are some of the date formats related hooks and functions have been removed:

  • hook_date_formats()
  • hook_date_formats_alter()
  • hook_date_format_types()
  • system_get_date_format()
  • system_get_date_formats()
  • system_get_date_types()

Migration examples from Drupal 7 to Drupal 8:

hook_date_formats()
hook_date_format_types()

Drupal 7:

function mymodule_date_format_types() {
  return array(
    'reversed_long' => t('Reversed Long'),
  );
}
function mymodule_date_formats() {
  return array(
    array(
      'type' => 'reversed_long',
      'format' => 'H:i - l, j F, Y',
      'locales' => array(),
    ),
  );
}

Drupal 8:

Create the mymodule/config/install/core.date_format.reversed_long.yml with the following code:

id: reversed_long
label: 'Reversed long date'
status: true
langcode: en
locked: true
pattern: 'H:i - l, j F, Y'

hook_date_formats_alter()

Drupal 7:

function mymodule_date_formats_alter(&$formats) {
  foreach ($formats as $id => $format) {
    $formats[$id]['locales'][] = 'en-ca';
  }
}
function mymodule_date_formats_alter(&$formats) {
  if (isset($formats['long'])) {
    $formats['long']['format'] = 'l - j F, Y';
  }
}

Drupal 8:

If you want to alter a single date format you can simply copy the associated config file (/core/modules/system/config/install/core.date_format.long.yml) to your custom module's config directory (/modules/custom/mymodyle/config/install/core.date_format.long.yml) and edit it as you want.

If you want to do a more complicated conditional alter you might want to check the documentation for the Configuration override system.

system_get_date_format()
system_get_date_formats()
system_get_date_types()

Since everything Drupal 8 is now using the file based configuration entities for defining date formats, in order to access the information you will need to make use of the configuration entity API (https://drupal.org/node/1500260)

Example:

$format = \Drupal\Core\Datetime\Entity\DateFormat:load('reversed_long');
Impacts: 
Site builders, administrators, editors
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: 
Other updates done

Comments

TR’s picture

system.date_format is now core.date_format

See issue Move datetime's FormElement #type classes in Core

<tr>.
bburg’s picture

I believe it should be core.date_format.[your date format].yml, not system.date_format.[your date format].yml. Is that right?

Metatag should be in core.