1 <?php
2
3 /*
4 * This file is part of the sfDateTimePlugin package.
5 * (c) 2007 Stephen Riesenberg <sjohnr@gmail.com>
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11 /**
12 *
13 * sfTime class.
14 *
15 * A library for manipulating dates in symfony (php).
16 *
17 * @package sfDateTimePlugin
18 * @author Stephen Riesenberg <sjohnr@gmail.com>
19 * @version SVN: $Id$
20 */
21 class sfTime
22 {
23 /**
24 * Units of time
25 */
26 const SECOND = 0;
27 const MINUTE = 1;
28 const HOUR = 2;
29 const DAY = 3;
30 const WEEK = 4;
31 const MONTH = 5;
32 const QUARTER = 6;
33 const YEAR = 7;
34 const DECADE = 8;
35 const CENTURY = 9;
36 const MILLENIUM = 10;
37
38 /**
39 * Days of the week
40 */
41 const MONDAY = 1;
42 const TUESDAY = 2;
43 const WEDNESDAY = 3;
44 const THURSDAY = 4;
45 const FRIDAY = 5;
46 const SATURDAY = 6;
47 const SUNDAY = 7;
48
49 /**
50 * Months of the year
51 */
52 const JANUARY = 1;
53 const FEBRUARY = 2;
54 const MARCH = 3;
55 const APRIL = 4;
56 const MAY = 5;
57 const JUNE = 6;
58 const JULY = 7;
59 const AUGUST = 8;
60 const SEPTEMBER = 9;
61 const OCTOBER = 10;
62 const NOVEMBER = 11;
63 const DECEMBER = 12;
64
65 /**
66 * Adds the specified number of given units of time to the given date.
67 *
68 * <b>Example:</b>
69 * <code>
70 * // tomorrow
71 * $dt = sfTime::add();
72 * // day after
73 * $dt = sfTime::add($mydate);
74 * // 5 days after
75 * $dt = sfTime::add($mydate, 5);
76 * // 2 months after
77 * $dt = sfTime::add($mydate, 2, sfTime::MONTH);
78 * // 4 weeks after
79 * $dt = sfTime::add($mydate, 4, sfTime::WEEK);
80 * </code>
81 *
82 * @param timestamp a timestamp for the calculation
83 * @param int the number of units to add to the given date
84 * @param int the unit to add by
85 * @return timestamp the timestamp result of the calculation
86 *
87 * @throws sfDateTimeException
88 */
89 public static function add($ts = null, $num = 1, $unit = sfTime::DAY)
90 {
91 // default to now
92 if ($ts === null) $ts = sfDateTimeToolkit::now();
93
94 // gather individual variables for readability and maintainability
95 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
96
97 // determine which unit of time to add by
98 switch ($unit)
99 {
100 case sfTime::SECOND:
101 return mktime($H, $i, $s + $num, $m, $d, $Y);
102 case sfTime::MINUTE:
103 return mktime($H, $i + $num, $s, $m, $d, $Y);
104 case sfTime::HOUR:
105 return mktime($H + $num, $i, $s, $m, $d, $Y);
106 case sfTime::DAY:
107 return mktime($H, $i, $s, $m, $d + $num, $Y);
108 case sfTime::WEEK:
109 return mktime($H, $i, $s, $m, $d + (7 * $num), $Y);
110 case sfTime::MONTH:
111 return mktime($H, $i, $s, $m + $num, $d, $Y);
112 case sfTime::QUARTER:
113 return mktime($H, $i, $s, $m + (3 * $num), $d, $Y);
114 case sfTime::YEAR:
115 return mktime($H, $i, $s, $m, $d, $Y + $num);
116 case sfTime::DECADE:
117 return mktime($H, $i, $s, $m, $d, $Y + (10 * $num));
118 case sfTime::CENTURY:
119 return mktime($H, $i, $s, $m, $d, $Y + (100 * $num));
120 case sfTime::MILLENIUM:
121 return mktime($H, $i, $s, $m, $d, $Y + (1000 * $num));
122 default:
123 throw new sfDateTimeException(sprintf('The unit of time provided is not valid: %s', $unit));
124 }
125 }
126
127 /**
128 * Subtracts the specified number of given units of time from the given date.
129 *
130 * <b>Example:</b>
131 * <code>
132 * // yesterday
133 * $dt = sfTime::subtract();
134 * // day before
135 * $dt = sfTime::subtract($mydate);
136 * // 5 days before
137 * $dt = sfTime::subtract($mydate, 5);
138 * // 2 months before
139 * $dt = sfTime::subtract($mydate, 2, sfTime::MONTH);
140 * // 4 weeks before
141 * $dt = sfTime::subtract($mydate, 4, sfTime::WEEK);
142 * </code>
143 *
144 * @param timestamp a timestamp for the calculation
145 * @param int the number of units to add to the given date
146 * @param int the unit to add by
147 * @return timestamp the timestamp result of the calculation
148 *
149 * @see add
150 */
151 public static function subtract($ts = null, $num = 1, $unit = sfTime::DAY)
152 {
153 return sfTime::add($ts, $num * -1, $unit);
154 }
155
156 /**
157 * Returns the timestamp with the date but without the time of day.
158 *
159 * @param timestamp
160 * @return timestamp
161 */
162 public static function clearTime($ts = null)
163 {
164 // default to now
165 if ($ts === null) $ts = sfDateTimeToolkit::now();
166
167 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
168
169 return mktime(0, 0, 0, $m, $d, $Y);
170 }
171
172 /**
173 * Returns the timestamp with the time of day but without the date.
174 *
175 * @deprecated This is a deprecated function. Do not use!
176 *
177 * @param timestamp
178 * @return timestamp
179 */
180 public static function clearDate($ts = null)
181 {
182 // default to now
183 if ($ts === null) $ts = sfDateTimeToolkit::now();
184
185 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
186
187 return mktime($H, $i, $s, 0, 0, 0);
188 }
189
190 /**
191 * Clear the second value of this timestamp.
192 *
193 * @param timestamp
194 * @param int
195 * @return timestamp
196 */
197 public static function clearSecond($ts = null)
198 {
199 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
200
201 return mktime($H, $i, 0, $m, $d, $Y);
202 }
203
204 /**
205 * Clear the minute value of this timestamp.
206 *
207 * @param timestamp
208 * @param int
209 * @return timestamp
210 */
211 public static function clearMinute($ts = null)
212 {
213 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
214
215 return mktime($H, 0, $s, $m, $d, $Y);
216 }
217
218 /**
219 * Clear the hour value of this timestamp.
220 *
221 * @param timestamp
222 * @param int
223 * @return timestamp
224 */
225 public static function clearHour($ts = null)
226 {
227 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
228
229 return mktime(0, $i, $s, $m, $d, $Y);
230 }
231
232 /**
233 * Set the second value of this timestamp.
234 *
235 * @param timestamp
236 * @param int
237 * @return timestamp
238 */
239 public static function setSecond($ts = null, $second = 0)
240 {
241 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
242
243 return mktime($H, $i, $second, $m, $d, $Y);
244 }
245
246 /**
247 * Set the minute value of this timestamp.
248 *
249 * @param timestamp
250 * @param int
251 * @return timestamp
252 */
253 public static function setMinute($ts = null, $minute = 0)
254 {
255 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
256
257 return mktime($H, $minute, $s, $m, $d, $Y);
258 }
259
260 /**
261 * Set the hour value of this timestamp.
262 *
263 * @param timestamp
264 * @param int
265 * @return timestamp
266 */
267 public static function setHour($ts = null, $hour = 0)
268 {
269 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
270
271 return mktime($hour, $i, $s, $m, $d, $Y);
272 }
273
274 /**
275 * Set the day value of this timestamp.
276 *
277 * @param timestamp
278 * @param int
279 * @return timestamp
280 */
281 public static function setDay($ts = null, $day = 1)
282 {
283 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
284
285 return mktime($H, $i, $s, $m, $day, $Y);
286 }
287
288 /**
289 * Set the month value of this timestamp.
290 *
291 * @param timestamp
292 * @param int
293 * @return timestamp
294 */
295 public static function setMonth($ts = null, $month = 1)
296 {
297 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
298
299 return mktime($H, $i, $s, $month, $d, $Y);
300 }
301
302 /**
303 * Set the year value of this timestamp.
304 *
305 * @param timestamp
306 * @param int
307 * @return timestamp
308 */
309 public static function setYear($ts = null, $year = 1970)
310 {
311 list($H, $i, $s, $m, $d, $Y) = sfDateTimeToolkit::breakdown($ts);
312
313 return mktime($H, $i, $s, $m, $d, $year);
314 }
315
316 /**
317 * Returns the timestamp for tomorrow.
318 *
319 * Alias for sfTime::addDay
320 *
321 * @param timestamp
322 * @return timestamp
323 */
324 public static function tomorrow($ts = null)
325 {
326 return sfTime::add($ts);
327 }
328
329 /**
330 * Returns the timestamp for yesterday.
331 *
332 * Alias for sfTime::subtractDay
333 *
334 * @param timestamp
335 * @return timestamp
336 */
337 public static function yesterday($ts = null)
338 {
339 return sfTime::subtract($ts);
340 }
341
342 /**
343 * Adds the specified number of seconds to the timestamp.
344 *
345 * @param timestamp
346 * @param int
347 * @return timestamp
348 */
349 public static function addSecond($ts = null, $num = 1)
350 {
351 return sfTime::add($ts, $num, sfTime::SECOND);
352 }
353
354 /**
355 * Subtracts the specified number of seconds from the timestamp.
356 *
357 * @param timestamp
358 * @param int
359 * @return timestamp
360 */
361 public static function subtractSecond($ts = null, $num = 1)
362 {
363 return sfTime::subtract($ts, $num, sfTime::SECOND);
364 }
365
366 /**
367 * Adds the specified number of minutes to the timestamp.
368 *
369 * @param timestamp
370 * @param int
371 * @return timestamp
372 */
373 public static function addMinute($ts = null, $num = 1)
374 {
375 return sfTime::add($ts, $num, sfTime::MINUTE);
376 }
377
378 /**
379 * Subtracts the specified number of minutes from the timestamp.
380 *
381 * @param timestamp
382 * @param int
383 * @return timestamp
384 */
385 public static function subtractMinute($ts = null, $num = 1)
386 {
387 return sfTime::subtract($ts, $num, sfTime::MINUTE);
388 }
389
390 /**
391 * Adds the specified number of hours to the timestamp.
392 *
393 * @param timestamp
394 * @param int
395 * @return timestamp
396 */
397 public static function addHour($ts = null, $num = 1)
398 {
399 return sfTime::add($ts, $num, sfTime::HOUR);
400 }
401
402 /**
403 * Subtracts the specified number of hours from the timestamp.
404 *
405 * @param timestamp
406 * @param int
407 * @return timestamp
408 */
409 public static function subtractHour($ts = null, $num = 1)
410 {
411 return sfTime::subtract($ts, $num, sfTime::HOUR);
412 }
413
414 /**
415 * Adds the specified number of days to the timestamp.
416 *
417 * @param timestamp
418 * @param int
419 * @return timestamp
420 */
421 public static function addDay($ts = null, $num = 1)
422 {
423 return sfTime::add($ts, $num, sfTime::DAY);
424 }
425
426 /**
427 * Subtracts the specified number of days from the timestamp.
428 *
429 * @param timestamp
430 * @param int
431 * @return timestamp
432 */
433 public static function subtractDay($ts = null, $num = 1)
434 {
435 return sfTime::subtract($ts, $num, sfTime::DAY);
436 }
437
438 /**
439 * Adds the specified number of weeks to the timestamp.
440 *
441 * @param timestamp
442 * @param int
443 * @return timestamp
444 */
445 public static function addWeek($ts = null, $num = 1)
446 {
447 return sfTime::add($ts, $num, sfTime::WEEK);
448 }
449
450 /**
451 * Subtracts the specified number of weeks from the timestamp.
452 *
453 * @param timestamp
454 * @param int
455 * @return timestamp
456 */
457 public static function subtractWeek($ts = null, $num = 1)
458 {
459 return sfTime::subtract($ts, $num, sfTime::WEEK);
460 }
461
462 /**
463 * Adds the specified number of months to the timestamp.
464 *
465 * @param timestamp
466 * @param int
467 * @return timestamp
468 */
469 public static function addMonth($ts = null, $num = 1)
470 {
471 return sfTime::add($ts, $num, sfTime::MONTH);
472 }
473
474 /**
475 * Subtracts the specified number of months from the timestamp.
476 *
477 * @param timestamp
478 * @param int
479 * @return timestamp
480 */
481 public static function subtractMonth($ts = null, $num = 1)
482 {
483 return sfTime::subtract($ts, $num, sfTime::MONTH);
484 }
485
486 /**
487 * Adds the specified number of quarters to the timestamp.
488 *
489 * @param timestamp
490 * @param int
491 * @return timestamp
492 */
493 public static function addQuarter($ts = null, $num = 1)
494 {
495 return sfTime::add($ts, $num, sfTime::QUARTER);
496 }
497
498 /**
499 * Subtracts the specified number of quarters from the timestamp.
500 *
501 * @param timestamp
502 * @param int
503 * @return timestamp
504 */
505 public static function subtractQuarter($ts = null, $num = 1)
506 {
507 return sfTime::subtract($ts, $num, sfTime::QUARTER);
508 }
509
510 /**
511 * Adds the specified number of years to the timestamp.
512 *
513 * @param timestamp
514 * @param int
515 * @return timestamp
516 */
517 public static function addYear($ts = null, $num = 1)
518 {
519 return sfTime::add($ts, $num, sfTime::YEAR);
520 }
521
522 /**
523 * Subtracts the specified number of years from the timestamp.
524 *
525 * @param timestamp
526 * @param int
527 * @return timestamp
528 */
529 public static function subtractYear($ts = null, $num = 1)
530 {
531 return sfTime::subtract($ts, $num, sfTime::YEAR);
532 }
533
534 /**
535 * Adds the specified number of decades to the timestamp.
536 *
537 * @param timestamp
538 * @param int
539 * @return timestamp
540 */
541 public static function addDecade($ts = null, $num = 1)
542 {
543 return sfTime::add($ts, $num, sfTime::DECADE);
544 }
545
546 /**
547 * Subtracts the specified number of decades from the timestamp.
548 *
549 * @param timestamp
550 * @param int
551 * @return timestamp
552 */
553 public static function subtractDecade($ts = null, $num = 1)
554 {
555 return sfTime::subtract($ts, $num, sfTime::DECADE);
556 }
557
558 /**
559 * Adds the specified number of centuries to the timestamp.
560 *
561 * @param timestamp
562 * @param int
563 * @return timestamp
564 */
565 public static function addCentury($ts = null, $num = 1)
566 {
567 return sfTime::add($ts, $num, sfTime::CENTURY);
568 }
569
570 /**
571 * Subtracts the specified number of centuries from the timestamp.
572 *
573 * @param timestamp
574 * @param int
575 * @return timestamp
576 */
577 public static function subtractCentury($ts = null, $num = 1)
578 {
579 return sfTime::subtract($ts, $num, sfTime::CENTURY);
580 }
581
582 /**
583 * Adds the specified number of millenia to the timestamp.
584 *
585 * @param timestamp
586 * @param int
587 * @return timestamp
588 */
589 public static function addMillenium($ts = null, $num = 1)
590 {
591 return sfTime::add($ts, $num, sfTime::MILLENIUM);
592 }
593
594 /**
595 * Subtracts the specified number of millenia from the timestamp.
596 *
597 * @param timestamp
598 * @param int
599 * @return timestamp
600 */
601 public static function subtractMillenium($ts = null, $num = 1)
602 {
603 return sfTime::subtract($ts, $num, sfTime::MILLENIUM);
604 }
605
606 /**
607 * Returns the timestamp for first day of the week for the given date.
608 *
609 * @param timestamp
610 * @return timestamp
611 */
612 public static function firstDayOfWeek($ts = null)
613 {
614 // default to now
615 if ($ts === null) $ts = sfDateTimeToolkit::now();
616 return sfTime::subtractDay($ts, date('N', $ts)-1);
617 }
618
619 /**
620 * Returns the timestamp for last day of the week for the given date.
621 *
622 * @param timestamp
623 * @return timestamp
624 */
625 public static function finalDayOfWeek($ts = null)
626 {
627 return sfTime::subtractDay(sfTime::firstDayOfWeek(sfTime::addWeek($ts)));
628 }
629
630 /**
631 * Returns the timestamp for first day of the month for the given date.
632 *
633 * @param timestamp
634 * @return timestamp
635 */
636 public static function firstDayOfMonth($ts = null)
637 {
638 // default to now
639 if ($ts === null) $ts = sfDateTimeToolkit::now();
640
641 return sfTime::subtractDay($ts, date('d', $ts) - 1);
642 }
643
644 /**
645 * Returns the timestamp for last day of the month for the given date.
646 *
647 * @param timestamp
648 * @return timestamp
649 */
650 public static function finalDayOfMonth($ts = null)
651 {
652 return sfTime::subtractDay(sfTime::firstDayOfMonth(sfTime::addMonth($ts)));
653 }
654
655 /**
656 * Returns the timestamp for first day of thequarter for the given date.
657 *
658 * NOTE: Computes the quarter as:
659 * <code>
660 * $quarter = ceil(date('m', $ts) / 3); // 1 - 4
661 * </code>
662 *
663 * @param timestamp
664 * @return timestamp
665 */
666 public static function firstDayOfQuarter($ts = null)
667 {
668 // default to now
669 if ($ts === null) $ts = sfDateTimeToolkit::now();
670
671 // variables for computation
672 $month = date('m', $ts);
673 $quarter = ceil($month / 3) - 1; // zero based quarter
674
675 return sfTime::subtractMonth(sfTime::firstDayOfMonth($ts), $month - ($quarter * 3) - 1);
676 }
677
678 /**
679 * Returns the timestamp for last day of the quarter for the given date.
680 *
681 * @param timestamp
682 * @return timestamp
683 */
684 public static function finalDayOfQuarter($ts = null)
685 {
686 return sfTime::subtractDay(sfTime::firstDayOfQuarter(sfTime::addQuarter($ts)));
687 }
688
689 /**
690 * Returns the timestamp for first day of the year for the given date.
691 *
692 * @param timestamp
693 * @return timestamp
694 */
695 public static function firstDayOfYear($ts = null)
696 {
697 // default to now
698 if ($ts === null) $ts = sfDateTimeToolkit::now();
699
700 return sfTime::subtractMonth(sfTime::firstDayOfMonth($ts), date('m', $ts) - 1);
701 }
702
703 /**
704 * Returns the timestamp for last day of the year for the given date.
705 *
706 * @param timestamp
707 * @return timestamp
708 */
709 public static function finalDayOfYear($ts = null)
710 {
711 return sfTime::subtractDay(sfTime::firstDayOfYear(sfTime::addYear($ts)));
712 }
713
714 /**
715 * Returns the timestamp for the next occurance of [day].
716 *
717 * @param timestamp
718 * @param int the day of week
719 * @return timestamp
720 */
721 public static function nextDay($ts = null, $day = sfTime::SUNDAY)
722 {
723 // default to now
724 if ($ts === null) $ts = sfDateTimeToolkit::now();
725
726 // get offsets from sunday
727 $offset1 = date('N', $ts);
728 $offset2 = $day;
729
730 // adjust if date wraps into next week
731 $offset2 += $offset2 > $offset1 ? 0 : 7;
732
733 return sfTime::addDay($ts, $offset2 - $offset1);
734 }
735
736 /**
737 * Returns the timestamp for the most recent (previous) occurance of [day].
738 *
739 * @param timestamp
740 * @param int the day of week
741 * @return timestamp
742 */
743 public static function previousDay($ts = null, $day = sfTime::SUNDAY)
744 {
745 // default to now
746 if ($ts === null) $ts = sfDateTimeToolkit::now();
747
748 // get offsets from sunday
749 $offset1 = date('N', $ts);
750 $offset2 = $day;
751
752 // adjust if date wraps into last week
753 $offset1 += $offset1 > $offset2 ? 0 : 7;
754
755 return sfTime::subtractDay($ts, $offset1 - $offset2);
756 }
757
758 /**
759 * Returns the timestamp for the next occurance of [month].
760 *
761 * @param timestamp
762 * @param int the month of year
763 * @return timestamp
764 */
765 public static function nextMonth($ts = null, $month = sfTime::JANUARY)
766 {
767 // default to now
768 if ($ts === null) $ts = sfDateTimeToolkit::now();
769
770 // get offsets from january
771 $offset1 = date('m', $ts);
772 $offset2 = $month;
773
774 // adjust if date wraps into next year
775 $offset2 += $offset2 > $offset1 ? 0 : 12;
776
777 return sfTime::addMonth($ts, $offset2 - $offset1);
778 }
779
780 /**
781 * Returns the timestamp for the most recent (previous) occurance of [month].
782 *
783 * @param timestamp
784 * @param int the month of year
785 * @return timestamp
786 */
787 public static function previousMonth($ts = null, $month = sfTime::JANUARY)
788 {
789 // default to now
790 if ($ts === null) $ts = sfDateTimeToolkit::now();
791
792 // get offsets from january
793 $offset1 = date('m', $ts);
794 $offset2 = $month;
795
796 // adjust if date wraps into last year
797 $offset1 += $offset1 > $offset2 ? 0 : 12;
798
799 return sfTime::subtractMonth($ts, $offset1 - $offset2);
800 }
801 }