Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * sfDateFormat 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:qiang.xue@gmail.com 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
 * @version    $Id: sfDateFormat.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
16
 * @package    symfony
17
 * @subpackage i18n
18
 */
19
 
20
/**
21
 * sfDateFormat class.
22
 *
23
 * The sfDateFormat class allows you to format dates and times with
24
 * predefined styles in a locale-sensitive manner. Formatting times
25
 * with the sfDateFormat class is similar to formatting dates.
26
 *
27
 * Formatting dates with the sfDateFormat class is a two-step process.
28
 * First, you create a formatter with the getDateInstance method.
29
 * Second, you invoke the format method, which returns a string containing
30
 * the formatted date.
31
 *
32
 * DateTime values are formatted using standard or custom patterns stored
33
 * in the properties of a DateTimeFormatInfo.
34
 *
35
 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com>
36
 * @version v1.0, last update on Sat Dec 04 14:10:49 EST 2004
37
 * @package    symfony
38
 * @subpackage i18n
39
 */
40
class sfDateFormat
41
{
42
  /**
43
   * A list of tokens and their function call.
44
   * @var array
45
   */
46
  protected $tokens = array(
47
    'G' => 'Era',
48
    'y' => 'year',
49
    'M' => 'mon',
50
    'd' => 'mday',
51
    'h' => 'Hour12',
52
    'H' => 'hours',
53
    'm' => 'minutes',
54
    's' => 'seconds',
55
    'E' => 'wday',
56
    'D' => 'yday',
57
    'F' => 'DayInMonth',
58
    'w' => 'WeekInYear',
59
    'W' => 'WeekInMonth',
60
    'a' => 'AMPM',
61
    'k' => 'HourInDay',
62
    'K' => 'HourInAMPM',
63
    'z' => 'TimeZone'
64
  );
65
 
66
  /**
67
   * A list of methods, to be used by the token function calls.
68
   * @var array
69
   */
70
  protected $methods = array();
71
 
72
  /**
73
   * The sfDateTimeFormatInfo, containing culture specific patterns and names.
74
   * @var sfDateTimeFormatInfo
75
   */
76
  protected $formatInfo;
77
 
78
  /**
79
   * Initializes a new sfDateFormat.
80
   *
81
   * @param mixed $formatInfo either, null, a sfCultureInfo instance, a DateTimeFormatInfo instance, or a locale.
82
   * @return sfDateFormat instance
83
   */
84
  function __construct($formatInfo = null)
85
  {
86
    if (null === $formatInfo)
87
    {
88
      $this->formatInfo = sfDateTimeFormatInfo::getInvariantInfo();
89
    }
90
    else if ($formatInfo instanceof sfCultureInfo)
91
    {
92
      $this->formatInfo = $formatInfo->DateTimeFormat;
93
    }
94
    else if ($formatInfo instanceof sfDateTimeFormatInfo)
95
    {
96
      $this->formatInfo = $formatInfo;
97
    }
98
    else
99
    {
100
      $this->formatInfo = sfDateTimeFormatInfo::getInstance($formatInfo);
101
    }
102
 
103
    $this->methods = get_class_methods($this);
104
  }
105
 
106
  /**
107
   * Guesses a date without calling strtotime.
108
   *
109
   * @author Olivier Verdier <Olivier.Verdier@gmail.com>
110
   * @param mixed  $time    the time as integer or string in strtotime format.
111
   * @param string $pattern the input pattern; default is sql date or timestamp
112
   * @return array same array as the getdate function
113
   */
114
  public function getDate($time, $pattern = null)
115
  {
116
    if (null === $time)
117
    {
118
      return null;
119
    }
120
 
121
    // if the type is not a php timestamp
122
    $isString = (string) $time !== (string) (int) $time;
123
 
124
    if ($isString)
125
    {
126
      if (!$pattern)
127
      {
128
        if (strlen($time) == 10)
129
        {
130
          $pattern = 'i';
131
        }
132
        else   // otherwise, default:
133
        {
134
          $pattern = 'I';
135
        }
136
      }
137
 
138
      $pattern = $this->getPattern($pattern);
139
      $tokens = $this->getTokens($pattern);
140
      $pregPattern = '';
141
      $matchNames = array();
142
      // current regex allows any char at the end. avoids duplicating [^\d]+ pattern
143
      // this could cause issues with utf character width
144
      $allowsAllChars=true;
145
      foreach ($tokens as $token)
146
      {
147
        if ($matchName = $this->getFunctionName($token))
148
        {
149
          $allowsAllChars = false;
150
          $pregPattern .= '(\d+)';
151
          $matchNames[] = $matchName;
152
        }
153
        else
154
        {
155
          if (!$allowsAllChars)
156
          {
157
            $allowsAllChars = true;
158
            $pregPattern .= '[^\d]+';
159
          }
160
        }
161
      }
162
      preg_match('@'.$pregPattern.'@', $time, $matches);
163
 
164
      array_shift($matches);
165
 
166
      if (count($matchNames) == count($matches))
167
      {
168
        $date = array_combine($matchNames, $matches);
169
        // guess the date if input with two digits
170
        if (strlen($date['year']) == 2)
171
        {
172
          $date['year'] = date('Y', mktime(0, 0, 0, 1, 1, $date['year']));
173
        }
174
        $date = array_map('intval', $date);
175
      }
176
    }
177
 
178
    // the last attempt has failed we fall back on the default method
179
    if (!isset($date))
180
    {
181
      if ($isString)
182
      {
183
        $numericalTime = @strtotime($time);
184
        if ($numericalTime === false)
185
        {
186
          throw new sfException(sprintf('Impossible to parse date "%s" with format "%s".', $time, $pattern));
187
        }
188
      }
189
      else
190
      {
191
        $numericalTime = $time;
192
      }
193
      $date = @getdate($numericalTime);
194
    }
195
 
196
    // we set default values for the time
197
    foreach (array('hours', 'minutes', 'seconds') as $timeDiv)
198
    {
199
      if (!isset($date[$timeDiv]))
200
      {
201
        $date[$timeDiv] = 0;
202
      }
203
    }
204
 
205
    return $date;
206
  }
207
 
208
  /**
209
   * Formats a date according to the pattern.
210
   *
211
   * @param mixed   $time           the time as integer or string in strtotime format.
212
   * @param string  $pattern        the pattern
213
   * @param string  $inputPattern   the input pattern
214
   * @param string  $charset        the charset
215
   * @return string formatted date time.
216
   */
217
  public function format($time, $pattern = 'F', $inputPattern = null, $charset = 'UTF-8')
218
  {
219
    $date = $this->getDate($time, $inputPattern);
220
 
221
    if (null === $pattern)
222
    {
223
      $pattern = 'F';
224
    }
225
 
226
    $pattern = $this->getPattern($pattern);
227
    $tokens = $this->getTokens($pattern);
228
 
229
    for ($i = 0, $max = count($tokens); $i < $max; $i++)
230
    {
231
      $pattern = $tokens[$i];
232
      if ($pattern{0} == "'" && $pattern{strlen($pattern) - 1} == "'")
233
      {
234
        $tokens[$i] = str_replace('``````', '\'', preg_replace('/(^\')|(\'$)/', '', $pattern));
235
      }
236
      else if ($pattern == '``````')
237
      {
238
        $tokens[$i] = '\'';
239
      }
240
      else
241
      {
242
        $function = ucfirst($this->getFunctionName($pattern));
243
        if ($function != null)
244
        {
245
          $fName = 'get'.$function;
246
          if (in_array($fName, $this->methods))
247
          {
248
            $tokens[$i] = $this->$fName($date, $pattern);
249
          }
250
          else
251
          {
252
            throw new sfException(sprintf('Function %s not found.', $function));
253
          }
254
        }
255
      }
256
    }
257
 
258
    return sfToolkit::I18N_toEncoding(implode('', $tokens), $charset);
259
  }
260
 
261
  /**
262
   * For a particular token, get the corresponding function to call.
263
   *
264
   * @param string $token token
265
   * @return mixed the function if good token, null otherwise.
266
   */
267
  protected function getFunctionName($token)
268
  {
269
    if (isset($this->tokens[$token{0}]))
270
    {
271
      return $this->tokens[$token{0}];
272
    }
273
  }
274
 
275
  /**
276
   * Gets the pattern from DateTimeFormatInfo or some predefined patterns.
277
   * If the $pattern parameter is an array of 2 element, it will assume
278
   * that the first element is the date, and second the time
279
   * and try to find an appropriate pattern and apply
280
   * DateTimeFormatInfo::formatDateTime
281
   * See the tutorial documentation for futher details on the patterns.
282
   *
283
   * @param mixed $pattern a pattern.
284
   * @return string a pattern.
285
   * @see DateTimeFormatInfo::formatDateTime()
286
   */
287
  public function getPattern($pattern)
288
  {
289
    if (is_array($pattern) && count($pattern) == 2)
290
    {
291
      return $this->formatInfo->formatDateTime($this->getPattern($pattern[0]), $this->getPattern($pattern[1]));
292
    }
293
 
294
    switch ($pattern)
295
    {
296
      case 'd':
297
        return $this->formatInfo->ShortDatePattern;
298
        break;
299
      case 'D':
300
        return $this->formatInfo->LongDatePattern;
301
        break;
302
      case 'p':
303
        return $this->formatInfo->MediumDatePattern;
304
        break;
305
      case 'P':
306
        return $this->formatInfo->FullDatePattern;
307
        break;
308
      case 't':
309
        return $this->formatInfo->ShortTimePattern;
310
        break;
311
      case 'T':
312
        return $this->formatInfo->LongTimePattern;
313
        break;
314
      case 'q':
315
        return $this->formatInfo->MediumTimePattern;
316
        break;
317
      case 'Q':
318
        return $this->formatInfo->FullTimePattern;
319
        break;
320
      case 'f':
321
        return $this->formatInfo->formatDateTime($this->formatInfo->LongDatePattern, $this->formatInfo->ShortTimePattern);
322
        break;
323
      case 'F':
324
        return $this->formatInfo->formatDateTime($this->formatInfo->LongDatePattern, $this->formatInfo->LongTimePattern);
325
        break;
326
      case 'g':
327
        return $this->formatInfo->formatDateTime($this->formatInfo->ShortDatePattern, $this->formatInfo->ShortTimePattern);
328
        break;
329
      case 'G':
330
        return $this->formatInfo->formatDateTime($this->formatInfo->ShortDatePattern, $this->formatInfo->LongTimePattern);
331
        break;
332
      case 'i':
333
        return 'yyyy-MM-dd';
334
        break;
335
      case 'I':
336
        return 'yyyy-MM-dd HH:mm:ss';
337
        break;
338
      case 'M':
339
      case 'm':
340
        return 'MMMM dd';
341
        break;
342
      case 'R':
343
      case 'r':
344
        return 'EEE, dd MMM yyyy HH:mm:ss';
345
        break;
346
      case 's':
347
        return 'yyyy-MM-ddTHH:mm:ss';
348
        break;
349
      case 'u':
350
        return 'yyyy-MM-dd HH:mm:ss z';
351
        break;
352
      case 'U':
353
        return 'EEEE dd MMMM yyyy HH:mm:ss';
354
        break;
355
      case 'Y':
356
      case 'y':
357
        return 'yyyy MMMM';
358
        break;
359
      default :
360
        return $pattern;
361
    }
362
  }
363
 
364
  /**
365
   * Returns an easy to parse input pattern
366
   * yy is replaced by yyyy and h by H
367
   *
368
   * @param string $pattern pattern.
369
   * @return string input pattern
370
   */
371
  public function getInputPattern($pattern)
372
  {
373
    $pattern = $this->getPattern($pattern);
374
 
375
    $pattern = strtr($pattern, array('yyyy' => 'Y', 'h'=>'H', 'z'=>'', 'a'=>''));
376
    $pattern = strtr($pattern, array('yy'=>'yyyy', 'Y'=>'yyyy'));
377
 
378
    return trim($pattern);
379
  }
380
 
381
  /**
382
   * Tokenizes the pattern. The tokens are delimited by group of
383
   * similar characters, e.g. 'aabb' will form 2 tokens of 'aa' and 'bb'.
384
   * Any substrings, starting and ending with a single quote (')
385
   * will be treated as a single token.
386
   *
387
   * @param string $pattern pattern.
388
   * @return array string tokens in an array.
389
   */
390
  protected function getTokens($pattern)
391
  {
392
    $char = null;
393
    $tokens = array();
394
    $token = null;
395
 
396
    $text = false;
397
 
398
    for ($i = 0, $max = strlen($pattern); $i < $max; $i++)
399
    {
400
      if ($char == null || $pattern{$i} == $char || $text)
401
      {
402
        $token .= $pattern{$i};
403
      }
404
      else
405
      {
406
        $tokens[] = str_replace("''", "'", $token);
407
        $token = $pattern{$i};
408
      }
409
 
410
      if ($pattern{$i} == "'" && $text == false)
411
      {
412
        $text = true;
413
      }
414
      else if ($text && $pattern{$i} == "'" && $char == "'")
415
      {
416
        $text = true;
417
      }
418
      else if ($text && $char != "'" && $pattern{$i} == "'")
419
      {
420
        $text = false;
421
      }
422
 
423
      $char = $pattern{$i};
424
 
425
    }
426
    $tokens[] = $token;
427
 
428
    return $tokens;
429
  }
430
 
431
  // makes a unix date from our incomplete $date array
432
  protected function getUnixDate($date)
433
  {
434
    return getdate(mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']));
435
  }
436
 
437
  /**
438
   * Gets the year.
439
   * "yy" will return the last two digits of year.
440
   * "y", "yyy" and "yyyy" will return the full integer year.
441
   *
442
   * @param array  $date    getdate format.
443
   * @param string $pattern a pattern.
444
   * @return string year
445
   */
446
  protected function getYear($date, $pattern = 'yyyy')
447
  {
448
    $year = $date['year'];
449
    switch ($pattern)
450
    {
451
      case 'yy':
452
        return substr($year, 2);
453
      case 'y':
454
      case 'yyy':
455
      case 'yyyy':
456
        return $year;
457
      default:
458
        throw new sfException('The pattern for year is either "y", "yy", "yyy" or "yyyy".');
459
    }
460
  }
461
 
462
  /**
463
   * Gets the month.
464
   * "M" will return integer 1 through 12
465
   * "MM" will return integer 1 through 12 padded with 0 to two characters width
466
   * "MMM" will return the abrreviated month name, e.g. "Jan"
467
   * "MMMM" will return the month name, e.g. "January"
468
   * "MMMMM" will return the narrow month name, e.g. "J"
469
   *
470
   * @param array   $date     getdate format.
471
   * @param string  $pattern  a pattern.
472
   * @return string month name
473
   */
474
  protected function getMon($date, $pattern = 'M')
475
  {
476
    $month = $date['mon'];
477
 
478
    switch ($pattern)
479
    {
480
      case 'M':
481
        return $month;
482
      case 'MM':
483
        return str_pad($month, 2, '0', STR_PAD_LEFT);
484
      case 'MMM':
485
        return $this->formatInfo->AbbreviatedMonthNames[$month - 1];
486
      case 'MMMM':
487
        return $this->formatInfo->MonthNames[$month - 1];
488
      case 'MMMMM':
489
        return $this->formatInfo->NarrowMonthNames[$month - 1];
490
      default:
491
        throw new sfException('The pattern for month is "M", "MM", "MMM", "MMMM", "MMMMM".');
492
    }
493
  }
494
 
495
  /**
496
   * Gets the day of the week.
497
   * "E" will return integer 0 (for Sunday) through 6 (for Saturday).
498
   * "EE" will return the narrow day of the week, e.g. "M"
499
   * "EEE" will return the abrreviated day of the week, e.g. "Mon"
500
   * "EEEE" will return the day of the week, e.g. "Monday"
501
   *
502
   * @param array   $date     getdate format.
503
   * @param string  $pattern  a pattern.
504
   * @return string day of the week.
505
   */
506
  protected function getWday($date, $pattern = 'EEEE')
507
  {
508
    // if the $date comes from our home-made get date
509
    if (!isset($date['wday']))
510
    {
511
      $date = $this->getUnixDate($date);
512
    }
513
    $day = $date['wday'];
514
 
515
    switch ($pattern)
516
    {
517
      case 'E':
518
        return $day;
519
        break;
520
      case 'EE':
521
        return $this->formatInfo->NarrowDayNames[$day];
522
      case 'EEE':
523
        return $this->formatInfo->AbbreviatedDayNames[$day];
524
        break;
525
      case 'EEEE':
526
        return $this->formatInfo->DayNames[$day];
527
        break;
528
      default:
529
        throw new sfException('The pattern for day of the week is "E", "EE", "EEE", or "EEEE".');
530
    }
531
  }
532
 
533
  /**
534
   * Gets the day of the month.
535
   * "d" for non-padding, "dd" will always return 2 characters.
536
   *
537
   * @param array   $date     getdate format.
538
   * @param string  $pattern  a pattern.
539
   * @return string day of the month
540
   */
541
  protected function getMday($date, $pattern = 'd')
542
  {
543
    $day = $date['mday'];
544
 
545
    switch ($pattern)
546
    {
547
      case 'd':
548
        return $day;
549
      case 'dd':
550
        return str_pad($day, 2, '0', STR_PAD_LEFT);
551
      case 'dddd':
552
        return $this->getWday($date);
553
      default:
554
        throw new sfException('The pattern for day of the month is "d", "dd" or "dddd".');
555
    }
556
  }
557
 
558
  /**
559
   * Gets the era. i.e. in gregorian, year > 0 is AD, else BC.
560
   *
561
   * @todo How to support multiple Eras?, e.g. Japanese.
562
   * @param array   $date     getdate format.
563
   * @param string  $pattern  a pattern.
564
   * @return string era
565
   */
566
  protected function getEra($date, $pattern = 'G')
567
  {
568
    if ($pattern != 'G')
569
    {
570
      throw new sfException('The pattern for era is "G".');
571
    }
572
 
573
    return $this->formatInfo->getEra($date['year'] > 0 ? 1 : 0);
574
  }
575
 
576
  /**
577
   * Gets the hours in 24 hour format, i.e. [0-23].
578
   * "H" for non-padding, "HH" will always return 2 characters.
579
   *
580
   * @param array   $date     getdate format.
581
   * @param string  $pattern  a pattern.
582
   * @return string hours in 24 hour format.
583
   */
584
  protected function getHours($date, $pattern = 'H')
585
  {
586
    $hour = $date['hours'];
587
 
588
    switch ($pattern)
589
    {
590
      case 'H':
591
        return $hour;
592
      case 'HH':
593
        return str_pad($hour, 2, '0', STR_PAD_LEFT);
594
      default:
595
        throw new sfException('The pattern for 24 hour format is "H" or "HH".');
596
    }
597
  }
598
 
599
  /**
600
   * Get the AM/PM designator, 12 noon is PM, 12 midnight is AM.
601
   *
602
   * @param array   $date     getdate format.
603
   * @param string  $pattern  a pattern.
604
   * @return string AM or PM designator
605
   */
606
  protected function getAMPM($date, $pattern = 'a')
607
  {
608
    if ($pattern != 'a')
609
    {
610
      throw new sfException('The pattern for AM/PM marker is "a".');
611
    }
612
 
613
    return $this->formatInfo->AMPMMarkers[intval($date['hours'] / 12)];
614
  }
615
 
616
  /**
617
   * Gets the hours in 12 hour format.
618
   * "h" for non-padding, "hh" will always return 2 characters.
619
   *
620
   * @param array   $date     getdate format.
621
   * @param string  $pattern  a pattern.
622
   * @return string hours in 12 hour format.
623
   */
624
  protected function getHour12($date, $pattern = 'h')
625
  {
626
    $hour = $date['hours'];
627
    $hour = ($hour == 12 | $hour == 0) ? 12 : $hour % 12;
628
 
629
    switch ($pattern)
630
    {
631
      case 'h':
632
        return $hour;
633
      case 'hh':
634
        return str_pad($hour, 2, '0', STR_PAD_LEFT);
635
      default:
636
        throw new sfException('The pattern for 24 hour format is "H" or "HH".');
637
    }
638
  }
639
 
640
  /**
641
   * Gets the minutes.
642
   * "m" for non-padding, "mm" will always return 2 characters.
643
   *
644
   * @param array   $date     getdate format.
645
   * @param string  $pattern  a pattern.
646
   * @return string minutes.
647
   */
648
  protected function getMinutes($date, $pattern = 'm')
649
  {
650
    $minutes = $date['minutes'];
651
 
652
    switch ($pattern)
653
    {
654
      case 'm':
655
        return $minutes;
656
      case 'mm':
657
        return str_pad($minutes, 2, '0', STR_PAD_LEFT);
658
      default:
659
        throw new sfException('The pattern for minutes is "m" or "mm".');
660
    }
661
  }
662
 
663
  /**
664
   * Gets the seconds.
665
   * "s" for non-padding, "ss" will always return 2 characters.
666
   *
667
   * @param array   $date     getdate format.
668
   * @param string  $pattern  a pattern.
669
   * @return string seconds
670
   */
671
  protected function getSeconds($date, $pattern = 's')
672
  {
673
    $seconds = $date['seconds'];
674
 
675
    switch ($pattern)
676
    {
677
      case 's':
678
        return $seconds;
679
      case 'ss':
680
        return str_pad($seconds, 2, '0', STR_PAD_LEFT);
681
      default:
682
        throw new sfException('The pattern for seconds is "s" or "ss".');
683
    }
684
  }
685
 
686
  /**
687
   * Gets the timezone from the server machine.
688
   *
689
   * @todo How to get the timezone for a different region?
690
   * @param array   $date     getdate format.
691
   * @param string  $pattern  a pattern.
692
   * @return string time zone
693
   */
694
  protected function getTimeZone($date, $pattern = 'z')
695
  {
696
    //mapping to PHP pattern symbols
697
    switch ($pattern)
698
    {
699
      case 'z':
700
        $pattern = 'T';
701
        break;
702
      case 'Z':
703
        $pattern = 'O';
704
      default:
705
        throw new sfException('The pattern for time zone is "z" or "Z".');
706
    }
707
 
708
    return @date($pattern, @mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']));
709
  }
710
 
711
  /**
712
   * Gets the day in the year, e.g. [1-366]
713
   *
714
   * @param array   $date     getdate format.
715
   * @param string  $pattern  a pattern.
716
   * @return int hours in AM/PM format.
717
   */
718
  protected function getYday($date, $pattern = 'D')
719
  {
720
    if ($pattern != 'D')
721
    {
722
      throw new sfException('The pattern for day in year is "D".');
723
    }
724
 
725
    return $date['yday'];
726
  }
727
 
728
  /**
729
   * Gets day in the month.
730
   *
731
   * @param array   $date     getdate format.
732
   * @param string  $pattern  a pattern.
733
   * @return int day in month
734
   */
735
  protected function getDayInMonth($date, $pattern = 'FF')
736
  {
737
    switch ($pattern)
738
    {
739
      case 'F':
740
        return @date('j', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']));
741
        break;
742
      case 'FF':
743
        return @date('d', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']));
744
        break;
745
      default:
746
        throw new sfException('The pattern for day in month is "F" or "FF".');
747
    }
748
  }
749
 
750
  /**
751
   * Gets the week in the year.
752
   *
753
   * @param array   $date     getdate format.
754
   * @param string  $pattern  a pattern.
755
   * @return int week in year
756
   */
757
  protected function getWeekInYear($date, $pattern = 'w')
758
  {
759
    if ($pattern != 'w')
760
    {
761
      throw new sfException('The pattern for week in year is "w".');
762
    }
763
 
764
    return @date('W', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year']));
765
  }
766
 
767
  /**
768
   * Gets week in the month.
769
   *
770
   * @param array   $date     getdate format.
771
   * @param string  $pattern  a pattern
772
   * @return int week in month
773
   */
774
  protected function getWeekInMonth($date, $pattern = 'W')
775
  {
776
    if ($pattern != 'W')
777
    {
778
      throw new sfException('The pattern for week in month is "W".');
779
    }
780
 
781
    return @date('W', @mktime(0, 0, 0, $date['mon'], $date['mday'], $date['year'])) - date('W', mktime(0, 0, 0, $date['mon'], 1, $date['year']));
782
  }
783
 
784
  /**
785
   * Gets the hours [1-24].
786
   *
787
   * @param array   $date     getdate format.
788
   * @param string  $pattern  a pattern.
789
   * @return int hours [1-24]
790
   */
791
  protected function getHourInDay($date, $pattern = 'k')
792
  {
793
    if ($pattern != 'k')
794
    {
795
      throw new sfException('The pattern for hour in day is "k".');
796
    }
797
 
798
    return $date['hours'] + 1;
799
  }
800
 
801
  /**
802
   * Gets the hours in AM/PM format, e.g [1-12]
803
   *
804
   * @param array   $date     getdate format.
805
   * @param string  $pattern  a pattern.
806
   * @return int hours in AM/PM format.
807
   */
808
  protected function getHourInAMPM($date, $pattern = 'K')
809
  {
810
    if ($pattern != 'K')
811
    {
812
      throw new sfException('The pattern for hour in AM/PM is "K".');
813
    }
814
 
815
    return ($date['hours'] + 1) % 12;
816
  }
817
}