Passed
Branch php-cs-fixer (b9836a)
by Fabio
15:02
created

DateFormat::getFunctionName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * DateFormat class file.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the BSD License.
7
 *
8
 * Copyright(c) 2004 by Qiang Xue. All rights reserved.
9
 *
10
 * To contact the author write to {@link mailto:[email protected] Qiang Xue}
11
 * The latest version of PRADO can be obtained from:
12
 * {@link http://prado.sourceforge.net/}
13
 *
14
 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
15
 * @package Prado\I18N\core
16
 */
17
18
namespace Prado\I18N\core;
19
20
/**
21
 * Get the DateTimeFormatInfo class.
22
 */
23
use Exception;
24
use Prado\Prado;
25
26
require_once(dirname(__FILE__) . '/DateTimeFormatInfo.php');
27
28
/**
29
 * Get the encoding utilities
30
 */
31
require_once(dirname(__FILE__) . '/util.php');
32
33
/**
34
 * DateFormat class.
35
 *
36
 * The DateFormat class allows you to format dates and times with
37
 * predefined styles in a locale-sensitive manner. Formatting times
38
 * with the DateFormat class is similar to formatting dates.
39
 *
40
 * Formatting dates with the DateFormat class is a two-step process.
41
 * First, you create a formatter with the getDateInstance method.
42
 * Second, you invoke the format method, which returns a string containing
43
 * the formatted date.
44
 *
45
 * DateTime values are formatted using standard or custom patterns stored
46
 * in the properties of a DateTimeFormatInfo.
47
 *
48
 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
49
 * @package Prado\I18N\core
50
 */
51
class DateFormat
52
{
53
	/**
54
	 * A list of tokens and their function call.
55
	 * @var array
56
	 */
57
	protected $tokens = [
58
			'G' => 'Era',
59
			'y' => 'Year',
60
			'M' => 'Month',
61
			'd' => 'Day',
62
			'h' => 'Hour12',
63
			'H' => 'Hour24',
64
			'm' => 'Minutes',
65
			's' => 'Seconds',
66
			'E' => 'DayInWeek',
67
			'D' => 'DayInYear',
68
			'F' => 'DayInMonth',
69
			'w' => 'WeekInYear',
70
			'W' => 'WeekInMonth',
71
			'a' => 'AMPM',
72
			'k' => 'HourInDay',
73
			'K' => 'HourInAMPM',
74
			'z' => 'TimeZone'
75
			];
76
77
	/**
78
	 * A list of methods, to be used by the token function calls.
79
	 * @var array
80
	 */
81
	protected $methods = [];
82
83
	/**
84
	 * The DateTimeFormatInfo, containing culture specific patterns and names.
85
	 * @var DateTimeFormatInfo
86
	 */
87
	protected $formatInfo;
88
89
	/**
90
	 * Initialize a new DateFormat.
91
	 * @param mixed either, null, a CultureInfo instance,
0 ignored issues
show
Bug introduced by
The type Prado\I18N\core\either was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
92
	 * a DateTimeFormatInfo instance, or a locale.
93
	 * @return DateFormat instance
94
	 */
95
	public function __construct($formatInfo = null)
96
	{
97
		if($formatInfo === null)
98
			$this->formatInfo = DateTimeFormatInfo::getInvariantInfo();
99
		elseif($formatInfo instanceof CultureInfo)
100
			$this->formatInfo = $formatInfo->DateTimeFormat;
0 ignored issues
show
Bug Best Practice introduced by
The property DateTimeFormat does not exist on Prado\I18N\core\CultureInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
101
		elseif($formatInfo instanceof DateTimeFormatInfo)
102
			$this->formatInfo = $formatInfo;
103
		else
104
			$this->formatInfo = DateTimeFormatInfo::getInstance($formatInfo);
105
106
		$this->methods = get_class_methods($this);
107
	}
108
109
	/**
110
	 * Format a date according to the pattern.
0 ignored issues
show
Bug introduced by
The type Prado\I18N\core\the was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
111
	 * @param mixed the time as integer or string in strtotime format.
112
	 * @return string formatted date time.
113
	 */
114
	public function format($time, $pattern = 'F', $charset = 'UTF-8')
115
	{
116
		if (is_numeric($time)) //assumes unix epoch
117
			$time = floatval($time);
118
		elseif(is_string($time))
119
			$time = @strtotime($time);
120
121
		if($pattern === null)
122
			$pattern = 'F';
123
124
		$date = new \DateTime;
125
		$date->setTimestamp($time);
126
127
		$pattern = $this->getPattern($pattern);
128
129
		$tokens = $this->getTokens($pattern);
130
131
		for($i = 0, $k = count($tokens); $i < $k; ++$i)
132
		{
133
			$pattern = $tokens[$i];
134
			if($pattern{0} == "'"
135
				&& $pattern{strlen($pattern) - 1} == "'")
136
			{
137
				$sub = preg_replace('/(^\')|(\'$)/', '', $pattern);
138
				$tokens[$i] = str_replace('``````', '\'', $sub);
139
			}
140
			elseif($pattern == '``````')
141
			{
142
				$tokens[$i] = '\'';
143
			}
144
			else
145
			{
146
				$function = $this->getFunctionName($pattern);
147
				if($function != null)
148
				{
149
					$fName = 'get' . $function;
150
					if(in_array($fName, $this->methods))
151
					{
152
						$rs = $this->$fName($date, $pattern);
153
						$tokens[$i] = $rs;
154
					}
155
					else
156
						throw new
157
						Exception('function ' . $function . ' not found.');
158
				}
159
			}
160
		}
161
162
		return I18N_toEncoding(implode('', $tokens), $charset);
0 ignored issues
show
Bug introduced by
implode('', $tokens) of type string is incompatible with the type Prado\I18N\core\the expected by parameter $string of Prado\I18N\core\I18N_toEncoding(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

162
		return I18N_toEncoding(/** @scrutinizer ignore-type */ implode('', $tokens), $charset);
Loading history...
163
	}
164
165
	/**
166
	 * For a particular token, get the corresponding function to call.
0 ignored issues
show
Bug introduced by
The type Prado\I18N\core\token was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
167
	 * @param string token
168
	 * @return mixed the function if good token, null otherwise.
169
	 */
170
	protected function getFunctionName($token)
171
	{
172
		if(isset($this->tokens[$token{0}]))
173
			return $this->tokens[$token{0}];
174
	}
175
176
	/**
177
	 * Get the pattern from DateTimeFormatInfo or some predefined patterns.
0 ignored issues
show
Bug introduced by
The type Prado\I18N\core\a was not found. Did you mean a? If so, make sure to prefix the type with \.
Loading history...
178
	 * If the $pattern parameter is an array of 2 element, it will assume
179
	 * that the first element is the date, and second the time
180
	 * and try to find an appropriate pattern and apply
181
	 * DateTimeFormatInfo::formatDateTime
182
	 * See the tutorial documentation for futher details on the patterns.
183
	 * @param mixed a pattern.
184
	 * @return string a pattern.
185
	 * @see DateTimeFormatInfo::formatDateTime()
186
	 */
187
	protected function getPattern($pattern)
188
	{
189
		if(is_array($pattern) && count($pattern) == 2)
190
		{
191
			return $this->formatInfo->formatDateTime(
192
							$this->getPattern($pattern[0]),
193
							$this->getPattern($pattern[1]));
194
		}
195
196
		switch($pattern)
197
		{
198
			case 'd':
199
				return $this->formatInfo->ShortDatePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property ShortDatePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
200
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
201
			case 'D':
202
				return $this->formatInfo->LongDatePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property LongDatePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
203
				break;
204
			case 'p':
205
				return $this->formatInfo->MediumDatePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property MediumDatePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
206
				break;
207
			case 'P':
208
				return $this->formatInfo->FullDatePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property FullDatePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
209
				break;
210
			case 't':
211
				return $this->formatInfo->ShortTimePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property ShortTimePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
212
				break;
213
			case 'T':
214
				return $this->formatInfo->LongTimePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property LongTimePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
215
				break;
216
			case 'q':
217
				return $this->formatInfo->MediumTimePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property MediumTimePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
218
				break;
219
			case 'Q':
220
				return $this->formatInfo->FullTimePattern;
0 ignored issues
show
Bug Best Practice introduced by
The property FullTimePattern does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
221
				break;
222
			case 'f':
223
				return $this->formatInfo->formatDateTime(
224
					$this->formatInfo->LongDatePattern,
225
					$this->formatInfo->ShortTimePattern);
226
				break;
227
			case 'F':
228
				return $this->formatInfo->formatDateTime(
229
					$this->formatInfo->LongDatePattern,
230
					$this->formatInfo->LongTimePattern);
231
				break;
232
			case 'g':
233
				return $this->formatInfo->formatDateTime(
234
					$this->formatInfo->ShortDatePattern,
235
					$this->formatInfo->ShortTimePattern);
236
				break;
237
			case 'G':
238
				return $this->formatInfo->formatDateTime(
239
					$this->formatInfo->ShortDatePattern,
240
					$this->formatInfo->LongTimePattern);
241
				break;
242
			case 'M':
243
			case 'm':
244
				return 'MMMM dd';
245
				break;
246
			case 'R':
247
			case 'r':
248
				return 'EEE, dd MMM yyyy HH:mm:ss';
249
				break;
250
			case 's':
251
				return 'yyyy-MM-ddTHH:mm:ss';
252
				break;
253
			case 'u':
254
				return 'yyyy-MM-dd HH:mm:ss z';
255
				break;
256
			case 'U':
257
				return 'EEEE dd MMMM yyyy HH:mm:ss';
258
				break;
259
			case 'Y':
260
			case 'y':
261
				return 'yyyy MMMM';
262
				break;
263
			default :
264
				return $pattern;
265
		}
266
	}
267
268
	/**
269
	 * Tokenize the pattern. The tokens are delimited by group of
270
	 * similar characters, e.g. 'aabb' will form 2 tokens of 'aa' and 'bb'.
271
	 * Any substrings, starting and ending with a single quote (')
272
	 * will be treated as a single token.
273
	 * @param string pattern.
274
	 * @return array string tokens in an array.
275
	 */
0 ignored issues
show
Documentation Bug introduced by
The doc comment pattern. at position 0 could not be parsed: Unknown type name 'pattern.' at position 0 in pattern..
Loading history...
276
	protected function getTokens($pattern)
277
	{
278
		$char = null;
279
		$tokens = [];
280
		$token = null;
281
282
		$text = false;
283
		$pattern = preg_replace("/''/", '``````', $pattern);
284
285
		for($i = 0; $i < strlen($pattern); $i++)
286
		{
287
			if($char == null || $pattern{$i} == $char || $text)
288
			{
289
				$token .= $pattern{$i};
290
			}
291
			else
292
			{
293
				$tokens[] = str_replace("", "'", $token);
294
				$token = $pattern{$i};
295
			}
296
297
			if($pattern{$i} == "'" && $text == false)
298
				$text = true;
299
			elseif($text && $pattern{$i} == "'" && $char == "'")
300
				$text = true;
301
			elseif($text && $char != "'" && $pattern{$i} == "'")
302
				$text = false;
303
304
			$char = $pattern{$i};
305
306
		}
307
		$tokens[] = $token;
308
		return $tokens;
309
	}
310
311
	/**
312
	 * Get the year.
313
	 * "yy" will return the last two digits of year.
314
	 * "yyyy" will return the full integer year.
315
	 * @param array getdate format.
0 ignored issues
show
Bug introduced by
The type Prado\I18N\core\getdate was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
316
	 * @param string a pattern.
317
	 * @return string year
318
	 */
319
	protected function getYear($date, $pattern = 'yyyy')
320
	{
321
		switch($pattern)
322
		{
323
			case 'yy':
324
				return $date->format('y');
325
			case 'yyyy':
326
				return $date->format('Y');
327
			default:
328
				throw new Exception('The pattern for year is either "yy" or "yyyy".');
329
		}
330
	}
331
332
	/**
333
	 * Get the month.
334
	 * "M" will return integer 1 through 12
335
	 * "MM" will return the narrow month name, e.g. "J"
336
	 * "MMM" will return the abrreviated month name, e.g. "Jan"
337
	 * "MMMM" will return the month name, e.g. "January"
338
	 * @param array getdate format.
339
	 * @param string a pattern.
340
	 * @return string month name
341
	 */
342
	protected function getMonth($date, $pattern = 'M')
343
	{
344
		switch($pattern)
345
		{
346
			case 'M':
347
				return $date->format('n');
348
			case 'MM':
349
				return $date->format('m');
350
			case 'MMM':
351
				return $this->formatInfo->AbbreviatedMonthNames[$date->format('n') - 1];
0 ignored issues
show
Bug Best Practice introduced by
The property AbbreviatedMonthNames does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
352
			case 'MMMM':
353
				return $this->formatInfo->MonthNames[$date->format('n') - 1];
0 ignored issues
show
Bug Best Practice introduced by
The property MonthNames does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
354
			default:
355
				throw new Exception('The pattern for month is "M", "MM", "MMM", or "MMMM".');
356
		}
357
	}
358
359
	/**
360
	 * Get the day of the week.
361
	 * "E" will return integer 0 (for Sunday) through 6 (for Saturday).
362
	 * "EE" will return the narrow day of the week, e.g. "M"
363
	 * "EEE" will return the abrreviated day of the week, e.g. "Mon"
364
	 * "EEEE" will return the day of the week, e.g. "Monday"
365
	 * @param array getdate format.
366
	 * @param string a pattern.
367
	 * @return string day of the week.
368
	 */
369
	protected function getDayInWeek($date, $pattern = 'EEEE')
370
	{
371
		$day = $date->format('w');
372
		switch($pattern)
373
		{
374
			case 'E':
375
				return $day;
376
			case 'EE':
377
				return $this->formatInfo->NarrowDayNames[$day];
0 ignored issues
show
Bug Best Practice introduced by
The property NarrowDayNames does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
378
			case 'EEE':
379
				return $this->formatInfo->AbbreviatedDayNames[$day];
0 ignored issues
show
Bug Best Practice introduced by
The property AbbreviatedDayNames does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
380
			case 'EEEE':
381
				return $this->formatInfo->DayNames[$day];
0 ignored issues
show
Bug Best Practice introduced by
The property DayNames does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
382
			default:
383
				throw new Exception('The pattern for day of the week is "E", "EE", "EEE", or "EEEE".');
384
		}
385
	}
386
387
	/**
388
	 * Get the day of the month.
389
	 * "d" for non-padding, "dd" will always return 2 characters.
390
	 * @param array getdate format.
391
	 * @param string a pattern.
392
	 * @return string day of the month
393
	 */
394
	protected function getDay($date, $pattern = 'd')
395
	{
396
		switch($pattern)
397
		{
398
			case 'd':
399
				return $date->format('j');
400
			case 'dd':
401
				return $date->format('d');
402
			default:
403
				throw new Exception('The pattern for day of the month is "d" or "dd".');
404
		}
405
	}
406
407
408
	/**
409
	 * Get the era. i.e. in gregorian, year > 0 is AD, else BC.
410
	 * @todo How to support multiple Eras?, e.g. Japanese.
411
	 * @param array getdate format.
412
	 * @param string a pattern.
413
	 * @return string era
414
	 */
415
	protected function getEra($date, $pattern = 'G')
416
	{
417
		if($pattern != 'G')
418
			throw new Exception('The pattern for era is "G".');
419
420
		$year = $date->format('Y');
421
		if($year > 0)
422
			return $this->formatInfo->getEra(1);
423
		else
424
			return $this->formatInfo->getEra(0);
425
	}
426
427
	/**
428
	 * Get the hours in 24 hour format, i.e. [0-23].
429
	 * "H" for non-padding, "HH" will always return 2 characters.
430
	 * @param array getdate format.
431
	 * @param string a pattern.
432
	 * @return string hours in 24 hour format.
433
	 */
434
	protected function getHour24($date, $pattern = 'H')
435
	{
436
		switch($pattern)
437
		{
438
			case 'H':
439
				return $date->format('G');
440
			case 'HH':
441
				return $date->format('H');
442
			default:
443
				throw new Exception('The pattern for 24 hour format is "H" or "HH".');
444
		}
445
	}
446
447
	/**
448
	 * Get the AM/PM designator, 12 noon is PM, 12 midnight is AM.
449
	 * @param array getdate format.
450
	 * @param string a pattern.
451
	 * @return string AM or PM designator
452
	 */
453
	protected function getAMPM($date, $pattern = 'a')
454
	{
455
		if($pattern != 'a')
456
			throw new Exception('The pattern for AM/PM marker is "a".');
457
458
		$hour = $date->format('G');
459
		$ampm = (int)($hour / 12);
460
		return $this->formatInfo->AMPMMarkers[$ampm];
0 ignored issues
show
Bug Best Practice introduced by
The property AMPMMarkers does not exist on Prado\I18N\core\DateTimeFormatInfo. Since you implemented __get, consider adding a @property annotation.
Loading history...
461
	}
462
463
	/**
464
	 * Get the hours in 12 hour format.
465
	 * "h" for non-padding, "hh" will always return 2 characters.
466
	 * @param array getdate format.
467
	 * @param string a pattern.
468
	 * @return string hours in 12 hour format.
469
	 */
470
	protected function getHour12($date, $pattern = 'h')
471
	{
472
		switch($pattern)
473
		{
474
			case 'h':
475
				return $date->format('g');
476
			case 'hh':
477
				return $date->format('h');
478
			default:
479
				throw new Exception('The pattern for 24 hour format is "H" or "HH".');
480
		}
481
	}
482
483
	/**
484
	 * Get the minutes.
485
	 * "m" for non-padding, "mm" will always return 2 characters.
486
	 * @param array getdate format.
487
	 * @param string a pattern.
488
	 * @return string minutes.
489
	 */
490
	protected function getMinutes($date, $pattern = 'm')
491
	{
492
		switch($pattern)
493
		{
494
			case 'm':
495
				return (int) $date->format('i');
496
			case 'mm':
497
				return $date->format('i');
498
			default:
499
				throw new Exception('The pattern for minutes is "m" or "mm".');
500
		}
501
	}
502
503
	/**
504
	 * Get the seconds.
505
	 * "s" for non-padding, "ss" will always return 2 characters.
506
	 * @param array getdate format.
507
	 * @param string a pattern.
508
	 * @return string seconds
509
	 */
510
	protected function getSeconds($date, $pattern = 's')
511
	{
512
		switch($pattern)
513
		{
514
			case 's':
515
				return (int) $date->format('s');
516
			case 'ss':
517
				return $date->format('s');
518
			default:
519
				throw new Exception('The pattern for seconds is "s" or "ss".');
520
		}
521
	}
522
523
	/**
524
	 * Get the timezone from the server machine.
525
	 * @todo How to get the timezone for a different region?
526
	 * @param array getdate format.
527
	 * @param string a pattern.
528
	 * @return string time zone
529
	 */
530
	protected function getTimeZone($date, $pattern = 'z')
531
	{
532
		if($pattern != 'z')
533
			throw new Exception('The pattern for time zone is "z".');
534
535
		return $date->format('T');
536
	}
537
538
	/**
539
	 * Get the day in the year, e.g. [1-366]
540
	 * @param array getdate format.
541
	 * @param string a pattern.
542
	 * @return int hours in AM/PM format.
543
	 */
544
	protected function getDayInYear($date, $pattern = 'D')
545
	{
546
		if($pattern != 'D')
547
			throw new Exception('The pattern for day in year is "D".');
548
549
		return $date->format('z');
550
	}
551
552
	/**
553
	 * Get day in the month.
554
	 * @param array getdate format.
555
	 * @param string a pattern.
556
	 * @return int day in month
557
	 */
558
	protected function getDayInMonth($date, $pattern = 'FF')
559
	{
560
		switch ($pattern) {
561
			case 'F':
562
				return $date->format('j');
563
			case 'FF':
564
				return $date->format('d');
565
			default:
566
				throw new Exception('The pattern for day in month is "F" or "FF".');
567
		}
568
	}
569
570
	/**
571
	 * Get the week in the year.
572
	 * @param array getdate format.
573
	 * @param string a pattern.
574
	 * @return int week in year
575
	 */
576
	protected function getWeekInYear($date, $pattern = 'w')
577
	{
578
		if($pattern != 'w')
579
			throw new Exception('The pattern for week in year is "w".');
580
581
		return $date->format('W');
582
	}
583
584
	/**
585
	 * Get week in the month.
586
	 * @param array getdate format.
587
	 * @return int week in month
588
	 */
589
	protected function getWeekInMonth($date, $pattern = 'W')
590
	{
591
		if($pattern != 'W')
592
			throw new Exception('The pattern for week in month is "W".');
593
594
		$firstInMonth = clone($date);
595
		$firstInMonth->setDate($firstInMonth->format('Y'), $firstInMonth->format('m'), 1);
596
		return $date->format('W') - $firstInMonth->format('W');
597
	}
598
599
	/**
600
	 * Get the hours [1-24].
601
	 * @param array getdate format.
602
	 * @param string a pattern.
603
	 * @return int hours [1-24]
604
	 */
605
	protected function getHourInDay($date, $pattern = 'k')
606
	{
607
		if($pattern != 'k')
608
			throw new Exception('The pattern for hour in day is "k".');
609
610
		return $date->format('G') + 1;
611
	}
612
613
	/**
614
	 * Get the hours in AM/PM format, e.g [1-12]
615
	 * @param array getdate format.
616
	 * @param string a pattern.
617
	 * @return int hours in AM/PM format.
618
	 */
619
	protected function getHourInAMPM($date, $pattern = 'K')
620
	{
621
		if($pattern != 'K')
622
			throw new Exception('The pattern for hour in AM/PM is "K".');
623
624
		return $date->format('g') + 1;
625
	}
626
}
627