b3a8ce75d603cd73ead25613b750fdc4551635a1
[yaffs-website] / web / core / lib / Drupal / Core / Datetime / DateHelper.php
1 <?php
2
3 namespace Drupal\Core\Datetime;
4
5 /**
6  * Defines Gregorian Calendar date values.
7  *
8  * Lots of helpful functions for use in massaging dates, specific to the
9  * Gregorian calendar system. The values include both translated and
10  * untranslated values.
11  *
12  * Untranslated values are useful as array keys and as css identifiers, and
13  * should be listed in English.
14  *
15  * Translated values are useful for display to the user. All values that need
16  * translation should be hard-coded and wrapped in t() so the translation system
17  * will be able to process them.
18  */
19 class DateHelper {
20
21   /**
22    * Constructs an untranslated array of month names.
23    *
24    * @return array
25    *   An array of month names.
26    */
27   public static function monthNamesUntranslated() {
28     // Force the key to use the correct month value, rather than
29     // starting with zero.
30     return [
31       1  => 'January',
32       2  => 'February',
33       3  => 'March',
34       4  => 'April',
35       5  => 'May',
36       6  => 'June',
37       7  => 'July',
38       8  => 'August',
39       9  => 'September',
40       10 => 'October',
41       11 => 'November',
42       12 => 'December',
43     ];
44   }
45
46   /**
47    * Constructs an untranslated array of abbreviated month names.
48    *
49    * @return array
50    *   An array of month names.
51    */
52   public static function monthNamesAbbrUntranslated() {
53     // Force the key to use the correct month value, rather than
54     // starting with zero.
55     return [
56       1  => 'Jan',
57       2  => 'Feb',
58       3  => 'Mar',
59       4  => 'Apr',
60       5  => 'May',
61       6  => 'Jun',
62       7  => 'Jul',
63       8  => 'Aug',
64       9  => 'Sep',
65       10 => 'Oct',
66       11 => 'Nov',
67       12 => 'Dec',
68     ];
69   }
70
71   /**
72    * Returns a translated array of month names.
73    *
74    * @param bool $required
75    *   (optional) If FALSE, the returned array will include a blank value.
76    *   Defaults to FALSE.
77    *
78    * @return array
79    *   An array of month names.
80    */
81   public static function monthNames($required = FALSE) {
82     // Force the key to use the correct month value, rather than
83     // starting with zero.
84     $monthnames = [
85       1  => t('January', [], ['context' => 'Long month name']),
86       2  => t('February', [], ['context' => 'Long month name']),
87       3  => t('March', [], ['context' => 'Long month name']),
88       4  => t('April', [], ['context' => 'Long month name']),
89       5  => t('May', [], ['context' => 'Long month name']),
90       6  => t('June', [], ['context' => 'Long month name']),
91       7  => t('July', [], ['context' => 'Long month name']),
92       8  => t('August', [], ['context' => 'Long month name']),
93       9  => t('September', [], ['context' => 'Long month name']),
94       10 => t('October', [], ['context' => 'Long month name']),
95       11 => t('November', [], ['context' => 'Long month name']),
96       12 => t('December', [], ['context' => 'Long month name']),
97     ];
98     $none = ['' => ''];
99     return !$required ? $none + $monthnames : $monthnames;
100   }
101
102   /**
103    * Constructs a translated array of month name abbreviations
104    *
105    * @param bool $required
106    *   (optional) If FALSE, the returned array will include a blank value.
107    *   Defaults to FALSE.
108    *
109    * @return array
110    *   An array of month abbreviations.
111    */
112   public static function monthNamesAbbr($required = FALSE) {
113     // Force the key to use the correct month value, rather than
114     // starting with zero.
115     $monthnames = [
116       1  => t('Jan', [], ['context' => 'Abbreviated month name']),
117       2  => t('Feb', [], ['context' => 'Abbreviated month name']),
118       3  => t('Mar', [], ['context' => 'Abbreviated month name']),
119       4  => t('Apr', [], ['context' => 'Abbreviated month name']),
120       5  => t('May', [], ['context' => 'Abbreviated month name']),
121       6  => t('Jun', [], ['context' => 'Abbreviated month name']),
122       7  => t('Jul', [], ['context' => 'Abbreviated month name']),
123       8  => t('Aug', [], ['context' => 'Abbreviated month name']),
124       9  => t('Sep', [], ['context' => 'Abbreviated month name']),
125       10 => t('Oct', [], ['context' => 'Abbreviated month name']),
126       11 => t('Nov', [], ['context' => 'Abbreviated month name']),
127       12 => t('Dec', [], ['context' => 'Abbreviated month name']),
128     ];
129     $none = ['' => ''];
130     return !$required ? $none + $monthnames : $monthnames;
131   }
132
133   /**
134    * Constructs an untranslated array of week days.
135    *
136    * @return array
137    *   An array of week day names
138    */
139   public static function weekDaysUntranslated() {
140     return [
141       'Sunday',
142       'Monday',
143       'Tuesday',
144       'Wednesday',
145       'Thursday',
146       'Friday',
147       'Saturday',
148     ];
149   }
150
151   /**
152    * Returns a translated array of week names.
153    *
154    * @param bool $required
155    *   (optional) If FALSE, the returned array will include a blank value.
156    *   Defaults to FALSE.
157    *
158    * @return array
159    *   An array of week day names
160    */
161   public static function weekDays($required = FALSE) {
162     $weekdays = [
163       t('Sunday'),
164       t('Monday'),
165       t('Tuesday'),
166       t('Wednesday'),
167       t('Thursday'),
168       t('Friday'),
169       t('Saturday'),
170     ];
171     $none = ['' => ''];
172     return !$required ? $none + $weekdays : $weekdays;
173   }
174
175   /**
176    * Constructs a translated array of week day abbreviations.
177    *
178    * @param bool $required
179    *   (optional) If FALSE, the returned array will include a blank value.
180    *   Defaults to FALSE.
181    *
182    * @return array
183    *   An array of week day abbreviations
184    */
185   public static function weekDaysAbbr($required = FALSE) {
186     $weekdays = [
187       t('Sun', [], ['context' => 'Abbreviated weekday']),
188       t('Mon', [], ['context' => 'Abbreviated weekday']),
189       t('Tue', [], ['context' => 'Abbreviated weekday']),
190       t('Wed', [], ['context' => 'Abbreviated weekday']),
191       t('Thu', [], ['context' => 'Abbreviated weekday']),
192       t('Fri', [], ['context' => 'Abbreviated weekday']),
193       t('Sat', [], ['context' => 'Abbreviated weekday']),
194     ];
195     $none = ['' => ''];
196     return !$required ? $none + $weekdays : $weekdays;
197   }
198
199   /**
200    * Constructs a translated array of 2-letter week day abbreviations.
201    *
202    * @param bool $required
203    *   (optional) If FALSE, the returned array will include a blank value.
204    *   Defaults to FALSE.
205    *
206    * @return array
207    *   An array of week day 2 letter abbreviations
208    */
209   public static function weekDaysAbbr2($required = FALSE) {
210     $weekdays = [
211       t('Su', [], ['context' => 'Abbreviated weekday']),
212       t('Mo', [], ['context' => 'Abbreviated weekday']),
213       t('Tu', [], ['context' => 'Abbreviated weekday']),
214       t('We', [], ['context' => 'Abbreviated weekday']),
215       t('Th', [], ['context' => 'Abbreviated weekday']),
216       t('Fr', [], ['context' => 'Abbreviated weekday']),
217       t('Sa', [], ['context' => 'Abbreviated weekday']),
218     ];
219     $none = ['' => ''];
220     return !$required ? $none + $weekdays : $weekdays;
221   }
222
223   /**
224    * Constructs a translated array of 1-letter week day abbreviations.
225    *
226    * @param bool $required
227    *   (optional) If FALSE, the returned array will include a blank value.
228    *   Defaults to FALSE.
229    *
230    * @return array
231    *   An array of week day 1 letter abbreviations
232    */
233   public static function weekDaysAbbr1($required = FALSE) {
234     $weekdays = [
235       t('S', [], ['context' => 'Abbreviated 1 letter weekday Sunday']),
236       t('M', [], ['context' => 'Abbreviated 1 letter weekday Monday']),
237       t('T', [], ['context' => 'Abbreviated 1 letter weekday Tuesday']),
238       t('W', [], ['context' => 'Abbreviated 1 letter weekday Wednesday']),
239       t('T', [], ['context' => 'Abbreviated 1 letter weekday Thursday']),
240       t('F', [], ['context' => 'Abbreviated 1 letter weekday Friday']),
241       t('S', [], ['context' => 'Abbreviated 1 letter weekday Saturday']),
242     ];
243     $none = ['' => ''];
244     return !$required ? $none + $weekdays : $weekdays;
245   }
246
247   /**
248    * Reorders weekdays to match the first day of the week.
249    *
250    * @param array $weekdays
251    *   An array of weekdays.
252    *
253    * @return array
254    *   An array of weekdays reordered to match the first day of the week. The
255    *   keys will remain unchanged. For example, if the first day of the week is
256    *   set to be Monday, the array keys will be [1, 2, 3, 4, 5, 6, 0].
257    */
258   public static function weekDaysOrdered($weekdays) {
259     $first_day = \Drupal::config('system.date')->get('first_day');
260     if ($first_day > 0) {
261       for ($i = 1; $i <= $first_day; $i++) {
262         // Reset the array to the first element.
263         reset($weekdays);
264         // Retrieve the first week day value.
265         $last = current($weekdays);
266         // Store the corresponding key.
267         $key = key($weekdays);
268         // Remove this week day from the beginning of the array.
269         unset($weekdays[$key]);
270         // Add this week day to the end of the array.
271         $weekdays[$key] = $last;
272       }
273     }
274     return $weekdays;
275   }
276
277   /**
278    * Constructs an array of years in a specified range.
279    *
280    * @param int $min
281    *   (optional) The minimum year in the array. Defaults to zero.
282    * @param int $max
283    *   (optional) The maximum year in the array. Defaults to zero.
284    * @param bool $required
285    *   (optional) If FALSE, the returned array will include a blank value.
286    *   Defaults to FALSE.
287    *
288    * @return array
289    *   An array of years in the selected range.
290    */
291   public static function years($min = 0, $max = 0, $required = FALSE) {
292     // Ensure $min and $max are valid values.
293     if (empty($min)) {
294       $min = intval(date('Y', REQUEST_TIME) - 3);
295     }
296     if (empty($max)) {
297       $max = intval(date('Y', REQUEST_TIME) + 3);
298     }
299     $none = ['' => ''];
300     $range = range($min, $max);
301     $range = array_combine($range, $range);
302     return !$required ? $none + $range : $range;
303   }
304
305   /**
306    * Constructs an array of days in a month.
307    *
308    * @param bool $required
309    *   (optional) If FALSE, the returned array will include a blank value.
310    *   Defaults to FALSE.
311    * @param int $month
312    *   (optional) The month in which to find the number of days. Defaults to
313    *   NULL.
314    * @param int $year
315    *   (optional) The year in which to find the number of days. Defaults to
316    *   NULL.
317    *
318    * @return array
319    *   An array of days for the selected month.
320    */
321   public static function days($required = FALSE, $month = NULL, $year = NULL) {
322     // If we have a month and year, find the right last day of the month.
323     if (!empty($month) && !empty($year)) {
324       $date = new DrupalDateTime($year . '-' . $month . '-01 00:00:00', 'UTC');
325       $max = $date->format('t');
326     }
327     // If there is no month and year given, default to 31.
328     if (empty($max)) {
329       $max = 31;
330     }
331     $none = ['' => ''];
332     $range = range(1, $max);
333     $range = array_combine($range, $range);
334     return !$required ? $none + $range : $range;
335   }
336
337
338   /**
339    * Constructs an array of hours.
340    *
341    * @param string $format
342    *   (optional) A date format string that indicates the format to use for the
343    *   hours. Defaults to 'H'.
344    * @param bool $required
345    *   (optional) If FALSE, the returned array will include a blank value.
346    *   Defaults to FALSE.
347    *
348    * @return array
349    *   An array of hours in the selected format.
350    */
351   public static function hours($format = 'H', $required = FALSE) {
352     $hours = [];
353     if ($format == 'h' || $format == 'g') {
354       $min = 1;
355       $max = 12;
356     }
357     else {
358       $min = 0;
359       $max = 23;
360     }
361     for ($i = $min; $i <= $max; $i++) {
362       $formatted = ($format == 'H' || $format == 'h') ? DrupalDateTime::datePad($i) : $i;
363       $hours[$i] = $formatted;
364     }
365     $none = ['' => ''];
366     return !$required ? $none + $hours : $hours;
367   }
368
369   /**
370    * Constructs an array of minutes.
371    *
372    * @param string $format
373    *   (optional) A date format string that indicates the format to use for the
374    *    minutes. Defaults to 'i'.
375    * @param bool $required
376    *   (optional) If FALSE, the returned array will include a blank value.
377    *   Defaults to FALSE.
378    * @param int $increment
379    *   An integer value to increment the values. Defaults to 1.
380    *
381    * @return array
382    *   An array of minutes in the selected format.
383    */
384   public static function minutes($format = 'i', $required = FALSE, $increment = 1) {
385     $minutes = [];
386     // Ensure $increment has a value so we don't loop endlessly.
387     if (empty($increment)) {
388       $increment = 1;
389     }
390     for ($i = 0; $i < 60; $i += $increment) {
391       $formatted = $format == 'i' ? DrupalDateTime::datePad($i) : $i;
392       $minutes[$i] = $formatted;
393     }
394     $none = ['' => ''];
395     return !$required ? $none + $minutes : $minutes;
396   }
397
398   /**
399    * Constructs an array of seconds.
400    *
401    * @param string $format
402    *   (optional) A date format string that indicates the format to use for the
403    *   seconds. Defaults to 's'.
404    * @param bool $required
405    *   (optional) If FALSE, the returned array will include a blank value.
406    *   Defaults to FALSE.
407    * @param int $increment
408    *   An integer value to increment the values. Defaults to 1.
409    *
410    * @return array
411    *   An array of seconds in the selected format.
412    */
413   public static function seconds($format = 's', $required = FALSE, $increment = 1) {
414     $seconds = [];
415     // Ensure $increment has a value so we don't loop endlessly.
416     if (empty($increment)) {
417       $increment = 1;
418     }
419     for ($i = 0; $i < 60; $i += $increment) {
420       $formatted = $format == 's' ? DrupalDateTime::datePad($i) : $i;
421       $seconds[$i] = $formatted;
422     }
423     $none = ['' => ''];
424     return !$required ? $none + $seconds : $seconds;
425   }
426
427   /**
428    * Constructs an array of AM and PM options.
429    *
430    * @param bool $required
431    *   (optional) If FALSE, the returned array will include a blank value.
432    *   Defaults to FALSE.
433    *
434    * @return array
435    *   An array of AM and PM options.
436    */
437   public static function ampm($required = FALSE) {
438     $none = ['' => ''];
439     $ampm = [
440              'am' => t('am', [], ['context' => 'ampm']),
441              'pm' => t('pm', [], ['context' => 'ampm']),
442             ];
443     return !$required ? $none + $ampm : $ampm;
444   }
445
446   /**
447    * Identifies the number of days in a month for a date.
448    *
449    * @param mixed $date
450    *   (optional) A DrupalDateTime object or a date string.
451    *   Defaults to NULL, which means to use the current date.
452    *
453    * @return int
454    *   The number of days in the month.
455    */
456   public static function daysInMonth($date = NULL) {
457     if (!$date instanceof DrupalDateTime) {
458       $date = new DrupalDateTime($date);
459     }
460     if (!$date->hasErrors()) {
461       return $date->format('t');
462     }
463     return NULL;
464   }
465
466   /**
467    * Identifies the number of days in a year for a date.
468    *
469    * @param mixed $date
470    *   (optional) A DrupalDateTime object or a date string.
471    *   Defaults to NULL, which means to use the current date.
472    *
473    * @return int
474    *   The number of days in the year.
475    */
476   public static function daysInYear($date = NULL) {
477     if (!$date instanceof DrupalDateTime) {
478       $date = new DrupalDateTime($date);
479     }
480     if (!$date->hasErrors()) {
481       if ($date->format('L')) {
482         return 366;
483       }
484       else {
485         return 365;
486       }
487     }
488     return NULL;
489   }
490
491   /**
492    * Returns day of week for a given date (0 = Sunday).
493    *
494    * @param mixed $date
495    *   (optional) A DrupalDateTime object or a date string.
496    *   Defaults to NULL, which means use the current date.
497    *
498    * @return int
499    *   The number of the day in the week.
500    */
501   public static function dayOfWeek($date = NULL) {
502     if (!$date instanceof DrupalDateTime) {
503       $date = new DrupalDateTime($date);
504     }
505     if (!$date->hasErrors()) {
506       return $date->format('w');
507     }
508     return NULL;
509   }
510
511   /**
512    * Returns translated name of the day of week for a given date.
513    *
514    * @param mixed $date
515    *   (optional) A DrupalDateTime object or a date string.
516    *   Defaults to NULL, which means use the current date.
517    * @param string $abbr
518    *   (optional) Whether to return the abbreviated name for that day.
519    *   Defaults to TRUE.
520    *
521    * @return string
522    *   The name of the day in the week for that date.
523    */
524   public static function dayOfWeekName($date = NULL, $abbr = TRUE) {
525     if (!$date instanceof DrupalDateTime) {
526       $date = new DrupalDateTime($date);
527     }
528     $dow = self::dayOfWeek($date);
529     $days = $abbr ? self::weekDaysAbbr() : self::weekDays();
530     return $days[$dow];
531   }
532
533 }