3 namespace Drupal\Core\Datetime;
5 use Drupal\Component\Datetime\DateTimePlus;
6 use Drupal\Core\StringTranslation\StringTranslationTrait;
9 * Extends DateTimePlus().
11 * This class extends the basic component and adds in Drupal-specific
12 * handling, like translation of the format() method.
14 * Static methods in base class can also be used to create DrupalDateTime objects.
17 * DrupalDateTime::createFromArray( array('year' => 2010, 'month' => 9, 'day' => 28) )
19 * @see \Drupal/Component/Datetime/DateTimePlus.php
21 class DrupalDateTime extends DateTimePlus {
23 use StringTranslationTrait;
26 * Format string translation cache.
28 protected $formatTranslationCache;
31 * Constructs a date object.
34 * A date/input_time_adjusted string. Defaults to 'now'.
35 * @param mixed $timezone
36 * PHP DateTimeZone object, string or NULL allowed.
38 * @param array $settings
39 * - validate_format: (optional) Boolean choice to validate the
40 * created date using the input format. The format used in
41 * createFromFormat() allows slightly different values than format().
42 * Using an input format that works in both functions makes it
43 * possible to a validation step to confirm that the date created
44 * from a format string exactly matches the input. This option
45 * indicates the format can be used for validation. Defaults to TRUE.
46 * - langcode: (optional) Used to control the result of the format() method.
48 * - debug: (optional) Boolean choice to leave debug values in the
49 * date object for debugging purposes. Defaults to FALSE.
51 public function __construct($time = 'now', $timezone = NULL, $settings = []) {
52 if (!isset($settings['langcode'])) {
53 $settings['langcode'] = \Drupal::languageManager()->getCurrentLanguage()->getId();
56 // Instantiate the parent class.
57 parent::__construct($time, $timezone, $settings);
62 * Overrides prepareTimezone().
64 * Override basic component timezone handling to use Drupal's
65 * knowledge of the preferred user timezone.
67 protected function prepareTimezone($timezone) {
68 if (empty($timezone)) {
69 // Fallback to user or system default timezone.
70 $timezone = drupal_get_user_timezone();
72 return parent::prepareTimezone($timezone);
78 * @param string $format
79 * A format string using either PHP's date().
80 * @param array $settings
81 * - timezone: (optional) String timezone name. Defaults to the timezone
83 * - langcode: (optional) String two letter language code used to control
84 * the result of the format() method. Defaults to NULL.
87 * The formatted value of the date. Since the format may contain user input,
88 * this value should be escaped when output.
90 public function format($format, $settings = []) {
91 $langcode = !empty($settings['langcode']) ? $settings['langcode'] : $this->langcode;
93 // Format the date and catch errors.
95 // Encode markers that should be translated. 'A' becomes
96 // '\xEF\AA\xFF'. xEF and xFF are invalid UTF-8 sequences,
97 // and we assume they are not in the input string.
98 // Paired backslashes are isolated to prevent errors in
99 // read-ahead evaluation. The read-ahead expression ensures that
100 // A matches, but not \A.
101 $format = preg_replace(['/\\\\\\\\/', '/(?<!\\\\)([AaeDlMTF])/'], ["\xEF\\\\\\\\\xFF", "\xEF\\\\\$1\$1\xFF"], $format);
103 // Call date_format().
104 $format = parent::format($format, $settings);
106 // Translates a formatted date string.
107 $translation_callback = function($matches) use ($langcode) {
109 $string = $matches[2];
110 if (!isset($this->formatTranslationCache[$langcode][$code][$string])) {
111 $options = ['langcode' => $langcode];
113 $options['context'] = 'Long month name';
117 $this->formatTranslationCache[$langcode][$code][$string] = $string;
120 $this->formatTranslationCache[$langcode][$code][$string] = $this->t($string, [], $options);
123 return $this->formatTranslationCache[$langcode][$code][$string];
126 // Translate the marked sequences.
127 $value = preg_replace_callback('/\xEF([AaeDlMTF]?)(.*?)\xFF/', $translation_callback, $format);
129 catch (\Exception $e) {
130 $this->errors[] = $e->getMessage();