Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Component/Datetime/DateTimePlus.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Component\Datetime; | |
4 | |
5 use Drupal\Component\Utility\ToStringTrait; | |
6 | |
7 /** | |
8 * Wraps DateTime(). | |
9 * | |
10 * This class wraps the PHP DateTime class with more flexible initialization | |
11 * parameters, allowing a date to be created from an existing date object, | |
12 * a timestamp, a string with an unknown format, a string with a known | |
13 * format, or an array of date parts. It also adds an errors array | |
14 * and a __toString() method to the date object. | |
15 * | |
16 * This class is less lenient than the DateTime class. It changes | |
17 * the default behavior for handling date values like '2011-00-00'. | |
18 * The DateTime class would convert that value to '2010-11-30' and report | |
19 * a warning but not an error. This extension treats that as an error. | |
20 * | |
21 * As with the DateTime class, a date object may be created even if it has | |
22 * errors. It has an errors array attached to it that explains what the | |
23 * errors are. This is less disruptive than allowing datetime exceptions | |
24 * to abort processing. The calling script can decide what to do about | |
25 * errors using hasErrors() and getErrors(). | |
26 */ | |
27 class DateTimePlus { | |
28 | |
29 use ToStringTrait; | |
30 | |
31 const FORMAT = 'Y-m-d H:i:s'; | |
32 | |
33 /** | |
34 * A RFC7231 Compliant date. | |
35 * | |
36 * http://tools.ietf.org/html/rfc7231#section-7.1.1.1 | |
37 * | |
38 * Example: Sun, 06 Nov 1994 08:49:37 GMT | |
39 */ | |
40 const RFC7231 = 'D, d M Y H:i:s \G\M\T'; | |
41 | |
42 /** | |
43 * An array of possible date parts. | |
44 */ | |
45 protected static $dateParts = [ | |
46 'year', | |
47 'month', | |
48 'day', | |
49 'hour', | |
50 'minute', | |
51 'second', | |
52 ]; | |
53 | |
54 /** | |
55 * The value of the time value passed to the constructor. | |
56 */ | |
57 protected $inputTimeRaw = ''; | |
58 | |
59 /** | |
60 * The prepared time, without timezone, for this date. | |
61 */ | |
62 protected $inputTimeAdjusted = ''; | |
63 | |
64 /** | |
65 * The value of the timezone passed to the constructor. | |
66 */ | |
67 protected $inputTimeZoneRaw = ''; | |
68 | |
69 /** | |
70 * The prepared timezone object used to construct this date. | |
71 */ | |
72 protected $inputTimeZoneAdjusted = ''; | |
73 | |
74 /** | |
75 * The value of the format passed to the constructor. | |
76 */ | |
77 protected $inputFormatRaw = ''; | |
78 | |
79 /** | |
80 * The prepared format, if provided. | |
81 */ | |
82 protected $inputFormatAdjusted = ''; | |
83 | |
84 /** | |
85 * The value of the language code passed to the constructor. | |
86 */ | |
87 protected $langcode = NULL; | |
88 | |
89 /** | |
90 * An array of errors encountered when creating this date. | |
91 */ | |
92 protected $errors = []; | |
93 | |
94 /** | |
95 * The DateTime object. | |
96 * | |
97 * @var \DateTime | |
98 */ | |
99 protected $dateTimeObject = NULL; | |
100 | |
101 /** | |
102 * Creates a date object from an input date object. | |
103 * | |
104 * @param \DateTime $datetime | |
105 * A DateTime object. | |
106 * @param array $settings | |
107 * @see __construct() | |
108 * | |
109 * @return static | |
110 * A new DateTimePlus object. | |
111 */ | |
112 public static function createFromDateTime(\DateTime $datetime, $settings = []) { | |
113 return new static($datetime->format(static::FORMAT), $datetime->getTimezone(), $settings); | |
114 } | |
115 | |
116 /** | |
117 * Creates a date object from an array of date parts. | |
118 * | |
119 * Converts the input value into an ISO date, forcing a full ISO | |
120 * date even if some values are missing. | |
121 * | |
122 * @param array $date_parts | |
123 * An array of date parts, like ('year' => 2014, 'month' => 4). | |
124 * @param mixed $timezone | |
125 * (optional) \DateTimeZone object, time zone string or NULL. NULL uses the | |
126 * default system time zone. Defaults to NULL. | |
127 * @param array $settings | |
128 * (optional) A keyed array for settings, suitable for passing on to | |
129 * __construct(). | |
130 * | |
131 * @return static | |
132 * A new DateTimePlus object. | |
133 * | |
134 * @throws \InvalidArgumentException | |
135 * If the array date values or value combination is not correct. | |
136 */ | |
137 public static function createFromArray(array $date_parts, $timezone = NULL, $settings = []) { | |
138 $date_parts = static::prepareArray($date_parts, TRUE); | |
139 if (static::checkArray($date_parts)) { | |
140 // Even with validation, we can end up with a value that the | |
141 // DateTime class won't handle, like a year outside the range | |
142 // of -9999 to 9999, which will pass checkdate() but | |
143 // fail to construct a date object. | |
144 $iso_date = static::arrayToISO($date_parts); | |
145 return new static($iso_date, $timezone, $settings); | |
146 } | |
147 else { | |
148 throw new \InvalidArgumentException('The array contains invalid values.'); | |
149 } | |
150 } | |
151 | |
152 /** | |
153 * Creates a date object from timestamp input. | |
154 * | |
155 * The timezone of a timestamp is always UTC. The timezone for a | |
156 * timestamp indicates the timezone used by the format() method. | |
157 * | |
158 * @param int $timestamp | |
159 * A UNIX timestamp. | |
160 * @param mixed $timezone | |
161 * @see __construct() | |
162 * @param array $settings | |
163 * @see __construct() | |
164 * | |
165 * @return static | |
166 * A new DateTimePlus object. | |
167 * | |
168 * @throws \InvalidArgumentException | |
169 * If the timestamp is not numeric. | |
170 */ | |
171 public static function createFromTimestamp($timestamp, $timezone = NULL, $settings = []) { | |
172 if (!is_numeric($timestamp)) { | |
173 throw new \InvalidArgumentException('The timestamp must be numeric.'); | |
174 } | |
175 $datetime = new static('', $timezone, $settings); | |
176 $datetime->setTimestamp($timestamp); | |
177 return $datetime; | |
178 } | |
179 | |
180 /** | |
181 * Creates a date object from an input format. | |
182 * | |
183 * @param string $format | |
184 * PHP date() type format for parsing the input. This is recommended | |
185 * to use things like negative years, which php's parser fails on, or | |
186 * any other specialized input with a known format. If provided the | |
187 * date will be created using the createFromFormat() method. | |
188 * @see http://php.net/manual/datetime.createfromformat.php | |
189 * @param mixed $time | |
190 * @see __construct() | |
191 * @param mixed $timezone | |
192 * @see __construct() | |
193 * @param array $settings | |
194 * - validate_format: (optional) Boolean choice to validate the | |
195 * created date using the input format. The format used in | |
196 * createFromFormat() allows slightly different values than format(). | |
197 * Using an input format that works in both functions makes it | |
198 * possible to a validation step to confirm that the date created | |
199 * from a format string exactly matches the input. This option | |
200 * indicates the format can be used for validation. Defaults to TRUE. | |
201 * @see __construct() | |
202 * | |
203 * @return static | |
204 * A new DateTimePlus object. | |
205 * | |
206 * @throws \InvalidArgumentException | |
207 * If the a date cannot be created from the given format. | |
208 * @throws \UnexpectedValueException | |
209 * If the created date does not match the input value. | |
210 */ | |
211 public static function createFromFormat($format, $time, $timezone = NULL, $settings = []) { | |
212 if (!isset($settings['validate_format'])) { | |
213 $settings['validate_format'] = TRUE; | |
214 } | |
215 | |
216 // Tries to create a date from the format and use it if possible. | |
217 // A regular try/catch won't work right here, if the value is | |
218 // invalid it doesn't return an exception. | |
219 $datetimeplus = new static('', $timezone, $settings); | |
220 | |
221 $date = \DateTime::createFromFormat($format, $time, $datetimeplus->getTimezone()); | |
222 if (!$date instanceof \DateTime) { | |
223 throw new \InvalidArgumentException('The date cannot be created from a format.'); | |
224 } | |
225 else { | |
226 // Functions that parse date is forgiving, it might create a date that | |
227 // is not exactly a match for the provided value, so test for that by | |
228 // re-creating the date/time formatted string and comparing it to the input. For | |
229 // instance, an input value of '11' using a format of Y (4 digits) gets | |
230 // created as '0011' instead of '2011'. | |
231 if ($date instanceof DateTimePlus) { | |
232 $test_time = $date->format($format, $settings); | |
233 } | |
234 elseif ($date instanceof \DateTime) { | |
235 $test_time = $date->format($format); | |
236 } | |
237 $datetimeplus->setTimestamp($date->getTimestamp()); | |
238 $datetimeplus->setTimezone($date->getTimezone()); | |
239 | |
240 if ($settings['validate_format'] && $test_time != $time) { | |
241 throw new \UnexpectedValueException('The created date does not match the input value.'); | |
242 } | |
243 } | |
244 return $datetimeplus; | |
245 } | |
246 | |
247 /** | |
248 * Constructs a date object set to a requested date and timezone. | |
249 * | |
250 * @param string $time | |
251 * (optional) A date/time string. Defaults to 'now'. | |
252 * @param mixed $timezone | |
253 * (optional) \DateTimeZone object, time zone string or NULL. NULL uses the | |
254 * default system time zone. Defaults to NULL. Note that the $timezone | |
255 * parameter and the current timezone are ignored when the $time parameter | |
256 * either is a UNIX timestamp (e.g. @946684800) or specifies a timezone | |
257 * (e.g. 2010-01-28T15:00:00+02:00). | |
258 * @see http://php.net/manual/en/datetime.construct.php | |
259 * @param array $settings | |
260 * (optional) Keyed array of settings. Defaults to empty array. | |
261 * - langcode: (optional) String two letter language code used to control | |
262 * the result of the format(). Defaults to NULL. | |
263 * - debug: (optional) Boolean choice to leave debug values in the | |
264 * date object for debugging purposes. Defaults to FALSE. | |
265 */ | |
266 public function __construct($time = 'now', $timezone = NULL, $settings = []) { | |
267 | |
268 // Unpack settings. | |
269 $this->langcode = !empty($settings['langcode']) ? $settings['langcode'] : NULL; | |
270 | |
271 // Massage the input values as necessary. | |
272 $prepared_time = $this->prepareTime($time); | |
273 $prepared_timezone = $this->prepareTimezone($timezone); | |
274 | |
275 try { | |
276 $this->errors = []; | |
277 if (!empty($prepared_time)) { | |
278 $test = date_parse($prepared_time); | |
279 if (!empty($test['errors'])) { | |
280 $this->errors = $test['errors']; | |
281 } | |
282 } | |
283 | |
284 if (empty($this->errors)) { | |
285 $this->dateTimeObject = new \DateTime($prepared_time, $prepared_timezone); | |
286 } | |
287 } | |
288 catch (\Exception $e) { | |
289 $this->errors[] = $e->getMessage(); | |
290 } | |
291 | |
292 // Clean up the error messages. | |
293 $this->checkErrors(); | |
294 } | |
295 | |
296 /** | |
297 * Renders the timezone name. | |
298 * | |
299 * @return string | |
300 */ | |
301 public function render() { | |
302 return $this->format(static::FORMAT) . ' ' . $this->getTimeZone()->getName(); | |
303 } | |
304 | |
305 /** | |
306 * Implements the magic __call method. | |
307 * | |
308 * Passes through all unknown calls onto the DateTime object. | |
309 * | |
310 * @param string $method | |
311 * The method to call on the decorated object. | |
312 * @param array $args | |
313 * Call arguments. | |
314 * | |
315 * @return mixed | |
316 * The return value from the method on the decorated object. If the proxied | |
317 * method call returns a DateTime object, then return the original | |
318 * DateTimePlus object, which allows function chaining to work properly. | |
319 * Otherwise, the value from the proxied method call is returned. | |
320 * | |
321 * @throws \Exception | |
322 * Thrown when the DateTime object is not set. | |
323 * @throws \BadMethodCallException | |
324 * Thrown when there is no corresponding method on the DateTime object to | |
325 * call. | |
326 */ | |
327 public function __call($method, array $args) { | |
328 // @todo consider using assert() as per https://www.drupal.org/node/2451793. | |
329 if (!isset($this->dateTimeObject)) { | |
330 throw new \Exception('DateTime object not set.'); | |
331 } | |
332 if (!method_exists($this->dateTimeObject, $method)) { | |
333 throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_class($this), $method)); | |
334 } | |
335 | |
336 $result = call_user_func_array([$this->dateTimeObject, $method], $args); | |
337 | |
338 return $result === $this->dateTimeObject ? $this : $result; | |
339 } | |
340 | |
341 /** | |
342 * Returns the difference between two DateTimePlus objects. | |
343 * | |
344 * @param \Drupal\Component\Datetime\DateTimePlus|\DateTime $datetime2 | |
345 * The date to compare to. | |
346 * @param bool $absolute | |
347 * Should the interval be forced to be positive? | |
348 * | |
349 * @return \DateInterval | |
350 * A DateInterval object representing the difference between the two dates. | |
351 * | |
352 * @throws \BadMethodCallException | |
353 * If the input isn't a DateTime or DateTimePlus object. | |
354 */ | |
355 public function diff($datetime2, $absolute = FALSE) { | |
356 if ($datetime2 instanceof DateTimePlus) { | |
357 $datetime2 = $datetime2->dateTimeObject; | |
358 } | |
359 if (!($datetime2 instanceof \DateTime)) { | |
360 throw new \BadMethodCallException(sprintf('Method %s expects parameter 1 to be a \DateTime or \Drupal\Component\Datetime\DateTimePlus object', __METHOD__)); | |
361 } | |
362 return $this->dateTimeObject->diff($datetime2, $absolute); | |
363 } | |
364 | |
365 /** | |
366 * Implements the magic __callStatic method. | |
367 * | |
368 * Passes through all unknown static calls onto the DateTime object. | |
369 */ | |
370 public static function __callStatic($method, $args) { | |
371 if (!method_exists('\DateTime', $method)) { | |
372 throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', get_called_class(), $method)); | |
373 } | |
374 return call_user_func_array(['\DateTime', $method], $args); | |
375 } | |
376 | |
377 /** | |
378 * Implements the magic __clone method. | |
379 * | |
380 * Deep-clones the DateTime object we're wrapping. | |
381 */ | |
382 public function __clone() { | |
383 $this->dateTimeObject = clone($this->dateTimeObject); | |
384 } | |
385 | |
386 /** | |
387 * Prepares the input time value. | |
388 * | |
389 * Changes the input value before trying to use it, if necessary. | |
390 * Can be overridden to handle special cases. | |
391 * | |
392 * @param mixed $time | |
393 * An input value, which could be a timestamp, a string, | |
394 * or an array of date parts. | |
395 * | |
396 * @return mixed | |
397 * The massaged time. | |
398 */ | |
399 protected function prepareTime($time) { | |
400 return $time; | |
401 } | |
402 | |
403 /** | |
404 * Prepares the input timezone value. | |
405 * | |
406 * Changes the timezone before trying to use it, if necessary. | |
407 * Most importantly, makes sure there is a valid timezone | |
408 * object before moving further. | |
409 * | |
410 * @param mixed $timezone | |
411 * Either a timezone name or a timezone object or NULL. | |
412 * | |
413 * @return \DateTimeZone | |
414 * The massaged time zone. | |
415 */ | |
416 protected function prepareTimezone($timezone) { | |
417 // If the input timezone is a valid timezone object, use it. | |
418 if ($timezone instanceof \DateTimezone) { | |
419 $timezone_adjusted = $timezone; | |
420 } | |
421 | |
422 // Allow string timezone input, and create a timezone from it. | |
423 elseif (!empty($timezone) && is_string($timezone)) { | |
424 $timezone_adjusted = new \DateTimeZone($timezone); | |
425 } | |
426 | |
427 // Default to the system timezone when not explicitly provided. | |
428 // If the system timezone is missing, use 'UTC'. | |
429 if (empty($timezone_adjusted) || !$timezone_adjusted instanceof \DateTimezone) { | |
430 $system_timezone = date_default_timezone_get(); | |
431 $timezone_name = !empty($system_timezone) ? $system_timezone : 'UTC'; | |
432 $timezone_adjusted = new \DateTimeZone($timezone_name); | |
433 } | |
434 | |
435 // We are finally certain that we have a usable timezone. | |
436 return $timezone_adjusted; | |
437 } | |
438 | |
439 /** | |
440 * Prepares the input format value. | |
441 * | |
442 * Changes the input format before trying to use it, if necessary. | |
443 * Can be overridden to handle special cases. | |
444 * | |
445 * @param string $format | |
446 * A PHP format string. | |
447 * | |
448 * @return string | |
449 * The massaged PHP format string. | |
450 */ | |
451 protected function prepareFormat($format) { | |
452 return $format; | |
453 } | |
454 | |
455 | |
456 /** | |
457 * Examines getLastErrors() to see what errors to report. | |
458 * | |
459 * Two kinds of errors are important: anything that DateTime | |
460 * considers an error, and also a warning that the date was invalid. | |
461 * PHP creates a valid date from invalid data with only a warning, | |
462 * 2011-02-30 becomes 2011-03-03, for instance, but we don't want that. | |
463 * | |
464 * @see http://php.net/manual/time.getlasterrors.php | |
465 */ | |
466 public function checkErrors() { | |
467 $errors = \DateTime::getLastErrors(); | |
468 if (!empty($errors['errors'])) { | |
469 $this->errors = array_merge($this->errors, $errors['errors']); | |
470 } | |
471 // Most warnings are messages that the date could not be parsed | |
472 // which causes it to be altered. For validation purposes, a warning | |
473 // as bad as an error, because it means the constructed date does | |
474 // not match the input value. | |
475 if (!empty($errors['warnings'])) { | |
476 $this->errors[] = 'The date is invalid.'; | |
477 } | |
478 | |
479 $this->errors = array_values(array_unique($this->errors)); | |
480 } | |
481 | |
482 /** | |
483 * Detects if there were errors in the processing of this date. | |
484 * | |
485 * @return bool | |
486 * TRUE if there were errors in the processing of this date, FALSE | |
487 * otherwise. | |
488 */ | |
489 public function hasErrors() { | |
490 return (boolean) count($this->errors); | |
491 } | |
492 | |
493 /** | |
494 * Gets error messages. | |
495 * | |
496 * Public function to return the error messages. | |
497 * | |
498 * @return array | |
499 * An array of errors encountered when creating this date. | |
500 */ | |
501 public function getErrors() { | |
502 return $this->errors; | |
503 } | |
504 | |
505 /** | |
506 * Creates an ISO date from an array of values. | |
507 * | |
508 * @param array $array | |
509 * An array of date values keyed by date part. | |
510 * @param bool $force_valid_date | |
511 * (optional) Whether to force a full date by filling in missing | |
512 * values. Defaults to FALSE. | |
513 * | |
514 * @return string | |
515 * The date as an ISO string. | |
516 */ | |
517 public static function arrayToISO($array, $force_valid_date = FALSE) { | |
518 $array = static::prepareArray($array, $force_valid_date); | |
519 $input_time = ''; | |
520 if ($array['year'] !== '') { | |
521 $input_time = static::datePad(intval($array['year']), 4); | |
522 if ($force_valid_date || $array['month'] !== '') { | |
523 $input_time .= '-' . static::datePad(intval($array['month'])); | |
524 if ($force_valid_date || $array['day'] !== '') { | |
525 $input_time .= '-' . static::datePad(intval($array['day'])); | |
526 } | |
527 } | |
528 } | |
529 if ($array['hour'] !== '') { | |
530 $input_time .= $input_time ? 'T' : ''; | |
531 $input_time .= static::datePad(intval($array['hour'])); | |
532 if ($force_valid_date || $array['minute'] !== '') { | |
533 $input_time .= ':' . static::datePad(intval($array['minute'])); | |
534 if ($force_valid_date || $array['second'] !== '') { | |
535 $input_time .= ':' . static::datePad(intval($array['second'])); | |
536 } | |
537 } | |
538 } | |
539 return $input_time; | |
540 } | |
541 | |
542 /** | |
543 * Creates a complete array from a possibly incomplete array of date parts. | |
544 * | |
545 * @param array $array | |
546 * An array of date values keyed by date part. | |
547 * @param bool $force_valid_date | |
548 * (optional) Whether to force a valid date by filling in missing | |
549 * values with valid values or just to use empty values instead. | |
550 * Defaults to FALSE. | |
551 * | |
552 * @return array | |
553 * A complete array of date parts. | |
554 */ | |
555 public static function prepareArray($array, $force_valid_date = FALSE) { | |
556 if ($force_valid_date) { | |
557 $now = new \DateTime(); | |
558 $array += [ | |
559 'year' => $now->format('Y'), | |
560 'month' => 1, | |
561 'day' => 1, | |
562 'hour' => 0, | |
563 'minute' => 0, | |
564 'second' => 0, | |
565 ]; | |
566 } | |
567 else { | |
568 $array += [ | |
569 'year' => '', | |
570 'month' => '', | |
571 'day' => '', | |
572 'hour' => '', | |
573 'minute' => '', | |
574 'second' => '', | |
575 ]; | |
576 } | |
577 return $array; | |
578 } | |
579 | |
580 /** | |
581 * Checks that arrays of date parts will create a valid date. | |
582 * | |
583 * Checks that an array of date parts has a year, month, and day, | |
584 * and that those values create a valid date. If time is provided, | |
585 * verifies that the time values are valid. Sort of an | |
586 * equivalent to checkdate(). | |
587 * | |
588 * @param array $array | |
589 * An array of datetime values keyed by date part. | |
590 * | |
591 * @return bool | |
592 * TRUE if the datetime parts contain valid values, otherwise FALSE. | |
593 */ | |
594 public static function checkArray($array) { | |
595 $valid_date = FALSE; | |
596 $valid_time = TRUE; | |
597 // Check for a valid date using checkdate(). Only values that | |
598 // meet that test are valid. | |
599 if (array_key_exists('year', $array) && array_key_exists('month', $array) && array_key_exists('day', $array)) { | |
600 if (@checkdate($array['month'], $array['day'], $array['year'])) { | |
601 $valid_date = TRUE; | |
602 } | |
603 } | |
604 // Testing for valid time is reversed. Missing time is OK, | |
605 // but incorrect values are not. | |
606 foreach (['hour', 'minute', 'second'] as $key) { | |
607 if (array_key_exists($key, $array)) { | |
608 $value = $array[$key]; | |
609 switch ($key) { | |
610 case 'hour': | |
611 if (!preg_match('/^([1-2][0-3]|[01]?[0-9])$/', $value)) { | |
612 $valid_time = FALSE; | |
613 } | |
614 break; | |
615 case 'minute': | |
616 case 'second': | |
617 default: | |
618 if (!preg_match('/^([0-5][0-9]|[0-9])$/', $value)) { | |
619 $valid_time = FALSE; | |
620 } | |
621 break; | |
622 } | |
623 } | |
624 } | |
625 return $valid_date && $valid_time; | |
626 } | |
627 | |
628 /** | |
629 * Pads date parts with zeros. | |
630 * | |
631 * Helper function for a task that is often required when working with dates. | |
632 * | |
633 * @param int $value | |
634 * The value to pad. | |
635 * @param int $size | |
636 * (optional) Size expected, usually 2 or 4. Defaults to 2. | |
637 * | |
638 * @return string | |
639 * The padded value. | |
640 */ | |
641 public static function datePad($value, $size = 2) { | |
642 return sprintf("%0" . $size . "d", $value); | |
643 } | |
644 | |
645 /** | |
646 * Formats the date for display. | |
647 * | |
648 * @param string $format | |
649 * A format string using either PHP's date(). | |
650 * @param array $settings | |
651 * - timezone: (optional) String timezone name. Defaults to the timezone | |
652 * of the date object. | |
653 * | |
654 * @return string|null | |
655 * The formatted value of the date or NULL if there were construction | |
656 * errors. | |
657 */ | |
658 public function format($format, $settings = []) { | |
659 | |
660 // If there were construction errors, we can't format the date. | |
661 if ($this->hasErrors()) { | |
662 return; | |
663 } | |
664 | |
665 // Format the date and catch errors. | |
666 try { | |
667 // Clone the date/time object so we can change the time zone without | |
668 // disturbing the value stored in the object. | |
669 $dateTimeObject = clone $this->dateTimeObject; | |
670 if (isset($settings['timezone'])) { | |
671 $dateTimeObject->setTimezone(new \DateTimeZone($settings['timezone'])); | |
672 } | |
673 $value = $dateTimeObject->format($format); | |
674 } | |
675 catch (\Exception $e) { | |
676 $this->errors[] = $e->getMessage(); | |
677 } | |
678 | |
679 return $value; | |
680 } | |
681 | |
682 } |