fix image text
[pear] / Date.php
1 <?php\r
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */\r
3 \r
4 // {{{ Header\r
5 \r
6 /**\r
7  * Generic date handling class for PEAR\r
8  *\r
9  * Generic date handling class for PEAR.  Attempts to be time zone aware\r
10  * through the Date::TimeZone class.  Supports several operations from\r
11  * Date::Calc on Date objects.\r
12  *\r
13  * PHP versions 4 and 5\r
14  *\r
15  * LICENSE:\r
16  *\r
17  * Copyright (c) 1997-2006 Baba Buehler, Pierre-Alain Joye\r
18  * All rights reserved.\r
19  *\r
20  * Redistribution and use in source and binary forms, with or without\r
21  * modification, are permitted under the terms of the BSD License.\r
22  *\r
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
27  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
31  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
33  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
34  * POSSIBILITY OF SUCH DAMAGE.\r
35  *\r
36  * @category   Date and Time\r
37  * @package    Date\r
38  * @author     Baba Buehler <baba@babaz.com>\r
39  * @author     Pierre-Alain Joye <pajoye@php.net>\r
40  * @author     Firman Wandayandi <firman@php.net>\r
41  * @copyright  1997-2006 Baba Buehler, Pierre-Alain Joye\r
42  * @license    http://www.opensource.org/licenses/bsd-license.php\r
43  *             BSD License\r
44  * @version    CVS: $Id: Date.php,v 1.41 2006/11/22 00:28:03 firman Exp $\r
45  * @link       http://pear.php.net/package/Date\r
46  */\r
47 \r
48 // }}}\r
49 \r
50 // {{{ Includes\r
51 \r
52 /**\r
53  * Load Date_TimeZone.\r
54  */\r
55 require_once 'Date/TimeZone.php';\r
56 \r
57 /**\r
58  * Load Date_Calc.\r
59  */\r
60 require_once 'Date/Calc.php';\r
61 \r
62 /**\r
63  * Load Date_Span.\r
64  */\r
65 require_once 'Date/Span.php';\r
66 \r
67 // }}}\r
68 // {{{ Constants\r
69 \r
70 // {{{ Output formats Pass this to getDate().\r
71 \r
72 /**\r
73  * "YYYY-MM-DD HH:MM:SS"\r
74  */\r
75 define('DATE_FORMAT_ISO', 1);\r
76 \r
77 /**\r
78  * "YYYYMMSSTHHMMSS(Z|(+/-)HHMM)?"\r
79  */\r
80 define('DATE_FORMAT_ISO_BASIC', 2);\r
81 \r
82 /**\r
83  * "YYYY-MM-SSTHH:MM:SS(Z|(+/-)HH:MM)?"\r
84  */\r
85 define('DATE_FORMAT_ISO_EXTENDED', 3);\r
86 \r
87 /**\r
88  * "YYYY-MM-SSTHH:MM:SS(.S*)?(Z|(+/-)HH:MM)?"\r
89  */\r
90 define('DATE_FORMAT_ISO_EXTENDED_MICROTIME', 6);\r
91 \r
92 /**\r
93  * "YYYYMMDDHHMMSS"\r
94  */\r
95 define('DATE_FORMAT_TIMESTAMP', 4);\r
96 \r
97 /**\r
98  * long int, seconds since the unix epoch\r
99  */\r
100 define('DATE_FORMAT_UNIXTIME', 5);\r
101 \r
102 // }}}\r
103 \r
104 // }}}\r
105 // {{{ Class: Date\r
106 \r
107 /**\r
108  * Generic date handling class for PEAR\r
109  *\r
110  * Generic date handling class for PEAR.  Attempts to be time zone aware\r
111  * through the Date::TimeZone class.  Supports several operations from\r
112  * Date::Calc on Date objects.\r
113  *\r
114  * @author     Baba Buehler <baba@babaz.com>\r
115  * @author     Pierre-Alain Joye <pajoye@php.net>\r
116  * @author     Firman Wandayandi <firman@php.net>\r
117  * @copyright  1997-2006 Baba Buehler, Pierre-Alain Joye\r
118  * @license    http://www.opensource.org/licenses/bsd-license.php\r
119  *             BSD License\r
120  * @version    Release: 1.4.7\r
121  * @link       http://pear.php.net/package/Date\r
122  */\r
123 class Date\r
124 {\r
125     // {{{ Properties\r
126 \r
127     /**\r
128      * the year\r
129      * @var int\r
130      */\r
131     var $year;\r
132 \r
133     /**\r
134      * the month\r
135      * @var int\r
136      */\r
137     var $month;\r
138 \r
139     /**\r
140      * the day\r
141      * @var int\r
142      */\r
143     var $day;\r
144 \r
145     /**\r
146      * the hour\r
147      * @var int\r
148      */\r
149     var $hour;\r
150 \r
151     /**\r
152      * the minute\r
153      * @var int\r
154      */\r
155     var $minute;\r
156 \r
157     /**\r
158      * the second\r
159      * @var int\r
160      */\r
161     var $second;\r
162 \r
163     /**\r
164      * the parts of a second\r
165      * @var float\r
166      */\r
167     var $partsecond;\r
168 \r
169     /**\r
170      * timezone for this date\r
171      * @var object Date_TimeZone\r
172      */\r
173     var $tz;\r
174 \r
175     /**\r
176      * define the default weekday abbreviation length\r
177      * used by ::format()\r
178      * @var int\r
179      */\r
180     var $getWeekdayAbbrnameLength = 3;\r
181 \r
182     // }}}\r
183     // {{{ Constructor\r
184 \r
185     /**\r
186      * Constructor\r
187      *\r
188      * Creates a new Date Object initialized to the current date/time in the\r
189      * system-default timezone by default.  A date optionally\r
190      * passed in may be in the ISO 8601, TIMESTAMP or UNIXTIME format,\r
191      * or another Date object.  If no date is passed, the current date/time\r
192      * is used.\r
193      *\r
194      * @access public\r
195      * @see setDate()\r
196      * @param mixed $date optional - date/time to initialize\r
197      * @return object Date the new Date object\r
198      */\r
199     function __construct($date = null)\r
200     {\r
201         $this->tz = Date_TimeZone::getDefault();\r
202         if (is_null($date)) {\r
203             $this->setDate(date("Y-m-d H:i:s"));\r
204         } elseif (is_a($date, 'Date')) {\r
205             $this->copy($date);\r
206         } else {\r
207             $this->setDate($date);\r
208         }\r
209     }\r
210 \r
211     // }}}\r
212     // {{{ setDate()\r
213 \r
214     /**\r
215      * Set the fields of a Date object based on the input date and format\r
216      *\r
217      * Set the fields of a Date object based on the input date and format,\r
218      * which is specified by the DATE_FORMAT_* constants.\r
219      *\r
220      * @access public\r
221      * @param string $date input date\r
222      * @param int $format Optional format constant (DATE_FORMAT_*) of the input date.\r
223      *                    This parameter isn't really needed anymore, but you could\r
224      *                    use it to force DATE_FORMAT_UNIXTIME.\r
225      */\r
226     function setDate($date, $format = DATE_FORMAT_ISO)\r
227     {\r
228         if (\r
229             preg_match('/^(\d{4})-?(\d{2})-?(\d{2})([T\s]?(\d{2}):?(\d{2}):?(\d{2})(\.\d+)?(Z|[\+\-]\d{2}:?\d{2})?)?$/i', $date, $regs)\r
230             && $format != DATE_FORMAT_UNIXTIME) {\r
231             // DATE_FORMAT_ISO, ISO_BASIC, ISO_EXTENDED, and TIMESTAMP\r
232             // These formats are extremely close to each other.  This regex\r
233             // is very loose and accepts almost any butchered format you could\r
234             // throw at it.  e.g. 2003-10-07 19:45:15 and 2003-10071945:15\r
235             // are the same thing in the eyes of this regex, even though the\r
236             // latter is not a valid ISO 8601 date.\r
237             $this->year       = $regs[1];\r
238             $this->month      = $regs[2];\r
239             $this->day        = $regs[3];\r
240             $this->hour       = isset($regs[5])?$regs[5]:0;\r
241             $this->minute     = isset($regs[6])?$regs[6]:0;\r
242             $this->second     = isset($regs[7])?$regs[7]:0;\r
243             $this->partsecond = isset($regs[8])?(float)$regs[8]:(float)0;\r
244 \r
245             // if an offset is defined, convert time to UTC\r
246             // Date currently can't set a timezone only by offset,\r
247             // so it has to store it as UTC\r
248             if (isset($regs[9])) {\r
249                 $this->toUTCbyOffset($regs[9]);\r
250             }\r
251         } elseif (is_numeric($date)) {\r
252             // UNIXTIME\r
253             $this->setDate(date("Y-m-d H:i:s", $date));\r
254         } else {\r
255             // unknown format\r
256             $this->year       = 0;\r
257             $this->month      = 1;\r
258             $this->day        = 1;\r
259             $this->hour       = 0;\r
260             $this->minute     = 0;\r
261             $this->second     = 0;\r
262             $this->partsecond = (float)0;\r
263         }\r
264     }\r
265 \r
266     // }}}\r
267     // {{{ getDate()\r
268 \r
269     /**\r
270      * Get a string (or other) representation of this date\r
271      *\r
272      * Get a string (or other) representation of this date in the\r
273      * format specified by the DATE_FORMAT_* constants.\r
274      *\r
275      * @access public\r
276      * @param int $format format constant (DATE_FORMAT_*) of the output date\r
277      * @return string the date in the requested format\r
278      */\r
279     function getDate($format = DATE_FORMAT_ISO)\r
280     {\r
281         switch ($format) {\r
282         case DATE_FORMAT_ISO:\r
283             return $this->format("%Y-%m-%d %T");\r
284             break;\r
285         case DATE_FORMAT_ISO_BASIC:\r
286             $format = "%Y%m%dT%H%M%S";\r
287             if ($this->tz->getID() == 'UTC') {\r
288                 $format .= "Z";\r
289             }\r
290             return $this->format($format);\r
291             break;\r
292         case DATE_FORMAT_ISO_EXTENDED:\r
293             $format = "%Y-%m-%dT%H:%M:%S";\r
294             if ($this->tz->getID() == 'UTC') {\r
295                 $format .= "Z";\r
296             }\r
297             return $this->format($format);\r
298             break;\r
299         case DATE_FORMAT_ISO_EXTENDED_MICROTIME:\r
300             $format = "%Y-%m-%dT%H:%M:%s";\r
301             if ($this->tz->getID() == 'UTC') {\r
302                 $format .= "Z";\r
303             }\r
304             return $this->format($format);\r
305             break;\r
306         case DATE_FORMAT_TIMESTAMP:\r
307             return $this->format("%Y%m%d%H%M%S");\r
308             break;\r
309         case DATE_FORMAT_UNIXTIME:\r
310             return mktime($this->hour, $this->minute, $this->second, $this->month, $this->day, $this->year);\r
311             break;\r
312         }\r
313     }\r
314 \r
315     // }}}\r
316     // {{{ copy()\r
317 \r
318     /**\r
319      * Copy values from another Date object\r
320      *\r
321      * Makes this Date a copy of another Date object.\r
322      *\r
323      * @access public\r
324      * @param object Date $date Date to copy from\r
325      */\r
326     function copy($date)\r
327     {\r
328         $this->year = $date->year;\r
329         $this->month = $date->month;\r
330         $this->day = $date->day;\r
331         $this->hour = $date->hour;\r
332         $this->minute = $date->minute;\r
333         $this->second = $date->second;\r
334         $this->tz = $date->tz;\r
335     }\r
336 \r
337     // }}}\r
338     // {{{ format()\r
339 \r
340     /**\r
341      *  Date pretty printing, similar to strftime()\r
342      *\r
343      *  Formats the date in the given format, much like\r
344      *  strftime().  Most strftime() options are supported.<br><br>\r
345      *\r
346      *  formatting options:<br><br>\r
347      *\r
348      *  <code>%a  </code>  abbreviated weekday name (Sun, Mon, Tue) <br>\r
349      *  <code>%A  </code>  full weekday name (Sunday, Monday, Tuesday) <br>\r
350      *  <code>%b  </code>  abbreviated month name (Jan, Feb, Mar) <br>\r
351      *  <code>%B  </code>  full month name (January, February, March) <br>\r
352      *  <code>%C  </code>  century number (the year divided by 100 and truncated to an integer, range 00 to 99) <br>\r
353      *  <code>%d  </code>  day of month (range 00 to 31) <br>\r
354      *  <code>%D  </code>  same as "%m/%d/%y" <br>\r
355      *  <code>%e  </code>  day of month, single digit (range 0 to 31) <br>\r
356      *  <code>%E  </code>  number of days since unspecified epoch (integer, Date_Calc::dateToDays()) <br>\r
357      *  <code>%H  </code>  hour as decimal number (00 to 23) <br>\r
358      *  <code>%I  </code>  hour as decimal number on 12-hour clock (01 to 12) <br>\r
359      *  <code>%j  </code>  day of year (range 001 to 366) <br>\r
360      *  <code>%m  </code>  month as decimal number (range 01 to 12) <br>\r
361      *  <code>%M  </code>  minute as a decimal number (00 to 59) <br>\r
362      *  <code>%n  </code>  newline character (\n) <br>\r
363      *  <code>%O  </code>  dst-corrected timezone offset expressed as "+/-HH:MM" <br>\r
364      *  <code>%o  </code>  raw timezone offset expressed as "+/-HH:MM" <br>\r
365      *  <code>%p  </code>  either 'am' or 'pm' depending on the time <br>\r
366      *  <code>%P  </code>  either 'AM' or 'PM' depending on the time <br>\r
367      *  <code>%r  </code>  time in am/pm notation, same as "%I:%M:%S %p" <br>\r
368      *  <code>%R  </code>  time in 24-hour notation, same as "%H:%M" <br>\r
369      *  <code>%s  </code>  seconds including the decimal representation smaller than one second <br>\r
370      *  <code>%S  </code>  seconds as a decimal number (00 to 59) <br>\r
371      *  <code>%t  </code>  tab character (\t) <br>\r
372      *  <code>%T  </code>  current time, same as "%H:%M:%S" <br>\r
373      *  <code>%w  </code>  weekday as decimal (0 = Sunday) <br>\r
374      *  <code>%U  </code>  week number of current year, first sunday as first week <br>\r
375      *  <code>%y  </code>  year as decimal (range 00 to 99) <br>\r
376      *  <code>%Y  </code>  year as decimal including century (range 0000 to 9999) <br>\r
377      *  <code>%%  </code>  literal '%' <br>\r
378      * <br>\r
379      *\r
380      * @access public\r
381      * @param string format the format string for returned date/time\r
382      * @return string date/time in given format\r
383      */\r
384     function format($format)\r
385     {\r
386         $output = "";\r
387 \r
388         for($strpos = 0; $strpos < strlen($format); $strpos++) {\r
389             $char = substr($format,$strpos,1);\r
390             if ($char == "%") {\r
391                 $nextchar = substr($format,$strpos + 1,1);\r
392                 switch ($nextchar) {\r
393                 case "a":\r
394                     $output .= Date_Calc::getWeekdayAbbrname($this->day,$this->month,$this->year, $this->getWeekdayAbbrnameLength);\r
395                     break;\r
396                 case "A":\r
397                     $output .= Date_Calc::getWeekdayFullname($this->day,$this->month,$this->year);\r
398                     break;\r
399                 case "b":\r
400                     $output .= Date_Calc::getMonthAbbrname($this->month);\r
401                     break;\r
402                 case "B":\r
403                     $output .= Date_Calc::getMonthFullname($this->month);\r
404                     break;\r
405                 case "C":\r
406                     $output .= sprintf("%02d",intval($this->year/100));\r
407                     break;\r
408                 case "d":\r
409                     $output .= sprintf("%02d",$this->day);\r
410                     break;\r
411                 case "D":\r
412                     $output .= sprintf("%02d/%02d/%02d",$this->month,$this->day,$this->year);\r
413                     break;\r
414                 case "e":\r
415                     $output .= $this->day * 1; // get rid of leading zero\r
416                     break;\r
417                 case "E":\r
418                     $output .= Date_Calc::dateToDays($this->day,$this->month,$this->year);\r
419                     break;\r
420                 case "H":\r
421                     $output .= sprintf("%02d", $this->hour);\r
422                     break;\r
423                 case 'h':\r
424                     $output .= sprintf("%d", $this->hour);\r
425                     break;\r
426                 case "I":\r
427                     $hour = ($this->hour + 1) > 12 ? $this->hour - 12 : $this->hour;\r
428                     $output .= sprintf("%02d", $hour==0 ? 12 : $hour);\r
429                     break;\r
430                 case "i":\r
431                     $hour = ($this->hour + 1) > 12 ? $this->hour - 12 : $this->hour;\r
432                     $output .= sprintf("%d", $hour==0 ? 12 : $hour);\r
433                     break;\r
434                 case "j":\r
435                     $output .= Date_Calc::julianDate($this->day,$this->month,$this->year);\r
436                     break;\r
437                 case "m":\r
438                     $output .= sprintf("%02d",$this->month);\r
439                     break;\r
440                 case "M":\r
441                     $output .= sprintf("%02d",$this->minute);\r
442                     break;\r
443                 case "n":\r
444                     $output .= "\n";\r
445                     break;\r
446                 case "O":\r
447                     $offms = $this->tz->getOffset($this);\r
448                     $direction = $offms >= 0 ? "+" : "-";\r
449                     $offmins = abs($offms) / 1000 / 60;\r
450                     $hours = $offmins / 60;\r
451                     $minutes = $offmins % 60;\r
452                     $output .= sprintf("%s%02d:%02d", $direction, $hours, $minutes);\r
453                     break;\r
454                 case "o":\r
455                     $offms = $this->tz->getRawOffset($this);\r
456                     $direction = $offms >= 0 ? "+" : "-";\r
457                     $offmins = abs($offms) / 1000 / 60;\r
458                     $hours = $offmins / 60;\r
459                     $minutes = $offmins % 60;\r
460                     $output .= sprintf("%s%02d:%02d", $direction, $hours, $minutes);\r
461                     break;\r
462                 case "p":\r
463                     $output .= $this->hour >= 12 ? "pm" : "am";\r
464                     break;\r
465                 case "P":\r
466                     $output .= $this->hour >= 12 ? "PM" : "AM";\r
467                     break;\r
468                 case "r":\r
469                     $hour = ($this->hour + 1) > 12 ? $this->hour - 12 : $this->hour;\r
470                     $output .= sprintf("%02d:%02d:%02d %s", $hour==0 ?  12 : $hour, $this->minute, $this->second, $this->hour >= 12 ? "PM" : "AM");\r
471                     break;\r
472                 case "R":\r
473                     $output .= sprintf("%02d:%02d", $this->hour, $this->minute);\r
474                     break;\r
475                 case "s":\r
476                     $output .= str_replace(',', '.', sprintf("%09f", (float)((float)$this->second + $this->partsecond)));\r
477                     break;\r
478                 case "S":\r
479                     $output .= sprintf("%02d", $this->second);\r
480                     break;\r
481                 case "t":\r
482                     $output .= "\t";\r
483                     break;\r
484                 case "T":\r
485                     $output .= sprintf("%02d:%02d:%02d", $this->hour, $this->minute, $this->second);\r
486                     break;\r
487                 case "w":\r
488                     $output .= Date_Calc::dayOfWeek($this->day,$this->month,$this->year);\r
489                     break;\r
490                 case "U":\r
491                     $output .= Date_Calc::weekOfYear($this->day,$this->month,$this->year);\r
492                     break;\r
493                 case "y":\r
494                     $output .= substr($this->year,2,2);\r
495                     break;\r
496                 case "Y":\r
497                     $output .= $this->year;\r
498                     break;\r
499                 case "Z":\r
500                     $output .= $this->tz->inDaylightTime($this) ? $this->tz->getDSTShortName() : $this->tz->getShortName();\r
501                     break;\r
502                 case "%":\r
503                     $output .= "%";\r
504                     break;\r
505                 default:\r
506                     $output .= $char.$nextchar;\r
507                 }\r
508                 $strpos++;\r
509             } else {\r
510                 $output .= $char;\r
511             }\r
512         }\r
513         return $output;\r
514 \r
515     }\r
516 \r
517     // }}}\r
518     // {{{ getTime()\r
519 \r
520     /**\r
521      * Get this date/time in Unix time() format\r
522      *\r
523      * Get a representation of this date in Unix time() format.  This may only be\r
524      * valid for dates from 1970 to ~2038.\r
525      *\r
526      * @access public\r
527      * @return int number of seconds since the unix epoch\r
528      */\r
529     function getTime()\r
530     {\r
531         return $this->getDate(DATE_FORMAT_UNIXTIME);\r
532     }\r
533 \r
534     // }}}\r
535     // {{{ setTZ()\r
536 \r
537     /**\r
538      * Sets the time zone of this Date\r
539      *\r
540      * Sets the time zone of this date with the given\r
541      * Date_TimeZone object.  Does not alter the date/time,\r
542      * only assigns a new time zone.  For conversion, use\r
543      * convertTZ().\r
544      *\r
545      * @access public\r
546      * @param object Date_TimeZone $tz the Date_TimeZone object to use, if called\r
547      * with a paramater that is not a Date_TimeZone object, will fall through to\r
548      * setTZbyID().\r
549      */\r
550     function setTZ($tz)\r
551     {\r
552         if(is_a($tz, 'Date_Timezone')) {\r
553             $this->tz = $tz;\r
554         } else {\r
555             $this->setTZbyID($tz);\r
556         }\r
557     }\r
558 \r
559     // }}}\r
560     // {{{ setTZbyID()\r
561 \r
562     /**\r
563      * Sets the time zone of this date with the given time zone id\r
564      *\r
565      * Sets the time zone of this date with the given\r
566      * time zone id, or to the system default if the\r
567      * given id is invalid. Does not alter the date/time,\r
568      * only assigns a new time zone.  For conversion, use\r
569      * convertTZ().\r
570      *\r
571      * @access public\r
572      * @param string id a time zone id\r
573      */\r
574     function setTZbyID($id)\r
575     {\r
576         if (Date_TimeZone::isValidID($id)) {\r
577             $this->tz = new Date_TimeZone($id);\r
578         } else {\r
579             $this->tz = Date_TimeZone::getDefault();\r
580         }\r
581     }\r
582 \r
583     // }}}\r
584     // {{{ inDaylightTime()\r
585 \r
586     /**\r
587      * Tests if this date/time is in DST\r
588      *\r
589      * Returns true if daylight savings time is in effect for\r
590      * this date in this date's time zone.  See Date_TimeZone::inDaylightTime()\r
591      * for compatability information.\r
592      *\r
593      * @access public\r
594      * @return boolean true if DST is in effect for this date\r
595      */\r
596     function inDaylightTime()\r
597     {\r
598         return $this->tz->inDaylightTime($this);\r
599     }\r
600 \r
601     // }}}\r
602     // {{{ toUTC()\r
603 \r
604     /**\r
605      * Converts this date to UTC and sets this date's timezone to UTC\r
606      *\r
607      * Converts this date to UTC and sets this date's timezone to UTC\r
608      *\r
609      * @access public\r
610      */\r
611     function toUTC()\r
612     {\r
613         if ($this->tz->getOffset($this) > 0) {\r
614             $this->subtractSeconds(intval($this->tz->getOffset($this) / 1000));\r
615         } else {\r
616             $this->addSeconds(intval(abs($this->tz->getOffset($this)) / 1000));\r
617         }\r
618         $this->tz = new Date_TimeZone('UTC');\r
619     }\r
620 \r
621     // }}}\r
622     // {{{ convertTZ()\r
623 \r
624     /**\r
625      * Converts this date to a new time zone\r
626      *\r
627      * Converts this date to a new time zone.\r
628      * WARNING: This may not work correctly if your system does not allow\r
629      * putenv() or if localtime() does not work in your environment.  See\r
630      * Date::TimeZone::inDaylightTime() for more information.\r
631      *\r
632      * @access public\r
633      * @param object Date_TimeZone $tz the Date::TimeZone object for the conversion time zone\r
634      */\r
635     function convertTZ($tz)\r
636     {\r
637         // convert to UTC\r
638         if ($this->tz->getOffset($this) > 0) {\r
639             $this->subtractSeconds(intval(abs($this->tz->getOffset($this)) / 1000));\r
640         } else {\r
641             $this->addSeconds(intval(abs($this->tz->getOffset($this)) / 1000));\r
642         }\r
643         // convert UTC to new timezone\r
644         if ($tz->getOffset($this) > 0) {\r
645             $this->addSeconds(intval(abs($tz->getOffset($this)) / 1000));\r
646         } else {\r
647             $this->subtractSeconds(intval(abs($tz->getOffset($this)) / 1000));\r
648         }\r
649         $this->tz = $tz;\r
650     }\r
651 \r
652     // }}}\r
653     // {{{ convertTZbyID()\r
654 \r
655     /**\r
656      * Converts this date to a new time zone, given a valid time zone ID\r
657      *\r
658      * Converts this date to a new time zone, given a valid time zone ID\r
659      * WARNING: This may not work correctly if your system does not allow\r
660      * putenv() or if localtime() does not work in your environment.  See\r
661      * Date::TimeZone::inDaylightTime() for more information.\r
662      *\r
663      * @access public\r
664      * @param string id a time zone id\r
665      */\r
666     function convertTZbyID($id)\r
667     {\r
668        if (Date_TimeZone::isValidID($id)) {\r
669           $tz = new Date_TimeZone($id);\r
670        } else {\r
671           $tz = Date_TimeZone::getDefault();\r
672        }\r
673        $this->convertTZ($tz);\r
674     }\r
675 \r
676     // }}}\r
677     // {{{ toUTCbyOffset()\r
678 \r
679     function toUTCbyOffset($offset)\r
680     {\r
681         if ($offset == "Z" || $offset == "+00:00" || $offset == "+0000") {\r
682             $this->toUTC();\r
683             return true;\r
684         }\r
685 \r
686         if (preg_match('/([\+\-])(\d{2}):?(\d{2})/', $offset, $regs)) {\r
687             // convert offset to seconds\r
688             $hours  = (int) isset($regs[2])?$regs[2]:0;\r
689             $mins   = (int) isset($regs[3])?$regs[3]:0;\r
690             $offset = ($hours * 3600) + ($mins * 60);\r
691 \r
692             if (isset($regs[1]) && $regs[1] == "-") {\r
693                 $offset *= -1;\r
694             }\r
695 \r
696             if ($offset > 0) {\r
697                 $this->subtractSeconds(intval($offset));\r
698             } else {\r
699                 $this->addSeconds(intval(abs($offset)));\r
700             }\r
701 \r
702             $this->tz = new Date_TimeZone('UTC');\r
703             return true;\r
704         }\r
705 \r
706         return false;\r
707     }\r
708 \r
709     // }}}\r
710     // {{{ addSeconds()\r
711 \r
712     /**\r
713      * Adds a given number of seconds to the date\r
714      *\r
715      * Adds a given number of seconds to the date\r
716      *\r
717      * @access public\r
718      * @param int $sec the number of seconds to add\r
719      */\r
720     function addSeconds($sec)\r
721     {\r
722         settype($sec, 'int');\r
723 \r
724         // Negative value given.\r
725         if ($sec < 0) {\r
726             $this->subtractSeconds(abs($sec));\r
727             return;\r
728         }\r
729 \r
730         $this->addSpan(new Date_Span($sec));\r
731     }\r
732 \r
733     // }}}\r
734     // {{{ addSpan()\r
735 \r
736     /**\r
737      * Adds a time span to the date\r
738      *\r
739      * Adds a time span to the date\r
740      *\r
741      * @access public\r
742      * @param object Date_Span $span the time span to add\r
743      */\r
744     function addSpan($span)\r
745     {\r
746         if (!is_a($span, 'Date_Span')) {\r
747             return;\r
748         }\r
749 \r
750         $this->second += $span->second;\r
751         if ($this->second >= 60) {\r
752             $this->minute++;\r
753             $this->second -= 60;\r
754         }\r
755 \r
756         $this->minute += $span->minute;\r
757         if ($this->minute >= 60) {\r
758             $this->hour++;\r
759             if ($this->hour >= 24) {\r
760                 list($this->year, $this->month, $this->day) =\r
761                     sscanf(Date_Calc::nextDay($this->day, $this->month, $this->year), "%04s%02s%02s");\r
762                 $this->hour -= 24;\r
763             }\r
764             $this->minute -= 60;\r
765         }\r
766 \r
767         $this->hour += $span->hour;\r
768         if ($this->hour >= 24) {\r
769             list($this->year, $this->month, $this->day) =\r
770                 sscanf(Date_Calc::nextDay($this->day, $this->month, $this->year), "%04s%02s%02s");\r
771             $this->hour -= 24;\r
772         }\r
773 \r
774         $d = Date_Calc::dateToDays($this->day, $this->month, $this->year);\r
775         $d += $span->day;\r
776 \r
777         list($this->year, $this->month, $this->day) =\r
778             sscanf(Date_Calc::daysToDate($d), "%04s%02s%02s");\r
779         $this->year  = intval($this->year);\r
780         $this->month = intval($this->month);\r
781         $this->day   = intval($this->day);\r
782     }\r
783 \r
784     // }}}\r
785     // {{{ subtractSeconds()\r
786 \r
787     /**\r
788      * Subtracts a given number of seconds from the date\r
789      *\r
790      * Subtracts a given number of seconds from the date\r
791      *\r
792      * @access public\r
793      * @param int $sec the number of seconds to subtract\r
794      */\r
795     function subtractSeconds($sec)\r
796     {\r
797         settype($sec, 'int');\r
798 \r
799         // Negative value given.\r
800         if ($sec < 0) {\r
801             $this->addSeconds(abs($sec));\r
802             return;\r
803         }\r
804 \r
805         $this->subtractSpan(new Date_Span($sec));\r
806     }\r
807 \r
808     // }}}\r
809     // {{{ subtractSpan()\r
810 \r
811     /**\r
812      * Subtracts a time span to the date\r
813      *\r
814      * Subtracts a time span to the date\r
815      *\r
816      * @access public\r
817      * @param object Date_Span $span the time span to subtract\r
818      */\r
819     function subtractSpan($span)\r
820     {\r
821         if (!is_a($span, 'Date_Span')) {\r
822             return;\r
823         }\r
824         if ($span->isEmpty()) {\r
825             return;\r
826         }\r
827 \r
828         $this->second -= $span->second;\r
829         if ($this->second < 0) {\r
830             $this->minute--;\r
831             $this->second += 60;\r
832         }\r
833 \r
834         $this->minute -= $span->minute;\r
835         if ($this->minute < 0) {\r
836             $this->hour--;\r
837             if ($this->hour < 0) {\r
838                 list($this->year, $this->month, $this->day) =\r
839                     sscanf(Date_Calc::prevDay($this->day, $this->month, $this->year), "%04s%02s%02s");\r
840                 $this->hour += 24;\r
841             }\r
842             $this->minute += 60;\r
843         }\r
844 \r
845         $this->hour -= $span->hour;\r
846         if ($this->hour < 0) {\r
847             list($this->year, $this->month, $this->day) =\r
848                 sscanf(Date_Calc::prevDay($this->day, $this->month, $this->year), "%04s%02s%02s");\r
849             $this->hour += 24;\r
850         }\r
851 \r
852         $d = Date_Calc::dateToDays($this->day, $this->month, $this->year);\r
853         $d -= $span->day;\r
854 \r
855         list($this->year, $this->month, $this->day) =\r
856             sscanf(Date_Calc::daysToDate($d), "%04s%02s%02s");\r
857         $this->year  = intval($this->year);\r
858         $this->month = intval($this->month);\r
859         $this->day   = intval($this->day);\r
860     }\r
861 \r
862     // }}}\r
863     // {{{ compare()\r
864 \r
865     /**\r
866      * Compares two dates\r
867      *\r
868      * Compares two dates.  Suitable for use\r
869      * in sorting functions.\r
870      *\r
871      * @access public\r
872      * @param object Date $d1 the first date\r
873      * @param object Date $d2 the second date\r
874      * @return int 0 if the dates are equal, -1 if d1 is before d2, 1 if d1 is after d2\r
875      */\r
876     function compare($d1, $d2)\r
877     {\r
878         $d1->convertTZ(new Date_TimeZone('UTC'));\r
879         $d2->convertTZ(new Date_TimeZone('UTC'));\r
880         $days1 = Date_Calc::dateToDays($d1->day, $d1->month, $d1->year);\r
881         $days2 = Date_Calc::dateToDays($d2->day, $d2->month, $d2->year);\r
882         if ($days1 < $days2) return -1;\r
883         if ($days1 > $days2) return 1;\r
884         if ($d1->hour < $d2->hour) return -1;\r
885         if ($d1->hour > $d2->hour) return 1;\r
886         if ($d1->minute < $d2->minute) return -1;\r
887         if ($d1->minute > $d2->minute) return 1;\r
888         if ($d1->second < $d2->second) return -1;\r
889         if ($d1->second > $d2->second) return 1;\r
890         return 0;\r
891     }\r
892 \r
893     // }}}\r
894     // {{{ before()\r
895 \r
896     /**\r
897      * Test if this date/time is before a certain date/time\r
898      *\r
899      * Test if this date/time is before a certain date/time\r
900      *\r
901      * @access public\r
902      * @param object Date $when the date to test against\r
903      * @return boolean true if this date is before $when\r
904      */\r
905     function before($when)\r
906     {\r
907         if (Date::compare($this,$when) == -1) {\r
908             return true;\r
909         } else {\r
910             return false;\r
911         }\r
912     }\r
913 \r
914     // }}}\r
915     // {{{ after()\r
916 \r
917     /**\r
918      * Test if this date/time is after a certian date/time\r
919      *\r
920      * Test if this date/time is after a certian date/time\r
921      *\r
922      * @access public\r
923      * @param object Date $when the date to test against\r
924      * @return boolean true if this date is after $when\r
925      */\r
926     function after($when)\r
927     {\r
928         if (Date::compare($this,$when) == 1) {\r
929             return true;\r
930         } else {\r
931             return false;\r
932         }\r
933     }\r
934 \r
935     // }}}\r
936     // {{{ equals()\r
937 \r
938     /**\r
939      * Test if this date/time is exactly equal to a certian date/time\r
940      *\r
941      * Test if this date/time is exactly equal to a certian date/time\r
942      *\r
943      * @access public\r
944      * @param object Date $when the date to test against\r
945      * @return boolean true if this date is exactly equal to $when\r
946      */\r
947     function equals($when)\r
948     {\r
949         if (Date::compare($this,$when) == 0) {\r
950             return true;\r
951         } else {\r
952             return false;\r
953         }\r
954     }\r
955 \r
956     // }}}\r
957     // {{{ isFuture()\r
958 \r
959     /**\r
960      * Determine if this date is in the future\r
961      *\r
962      * Determine if this date is in the future\r
963      *\r
964      * @access public\r
965      * @return boolean true if this date is in the future\r
966      */\r
967     function isFuture()\r
968     {\r
969         $now = new Date();\r
970         if ($this->after($now)) {\r
971             return true;\r
972         } else {\r
973             return false;\r
974         }\r
975     }\r
976 \r
977     // }}}\r
978     // {{{ isPast()\r
979 \r
980     /**\r
981      * Determine if this date is in the past\r
982      *\r
983      * Determine if this date is in the past\r
984      *\r
985      * @access public\r
986      * @return boolean true if this date is in the past\r
987      */\r
988     function isPast()\r
989     {\r
990         $now = new Date();\r
991         if ($this->before($now)) {\r
992             return true;\r
993         } else {\r
994             return false;\r
995         }\r
996     }\r
997 \r
998     // }}}\r
999     // {{{ isLeapYear()\r
1000 \r
1001     /**\r
1002      * Determine if the year in this date is a leap year\r
1003      *\r
1004      * Determine if the year in this date is a leap year\r
1005      *\r
1006      * @access public\r
1007      * @return boolean true if this year is a leap year\r
1008      */\r
1009     function isLeapYear()\r
1010     {\r
1011         return Date_Calc::isLeapYear($this->year);\r
1012     }\r
1013 \r
1014     // }}}\r
1015     // {{{ getJulianDate()\r
1016 \r
1017     /**\r
1018      * Get the Julian date for this date\r
1019      *\r
1020      * Get the Julian date for this date\r
1021      *\r
1022      * @access public\r
1023      * @return int the Julian date\r
1024      */\r
1025     function getJulianDate()\r
1026     {\r
1027         return Date_Calc::julianDate($this->day, $this->month, $this->year);\r
1028     }\r
1029 \r
1030     // }}}\r
1031     // {{{ getDayOfWeek()\r
1032 \r
1033     /**\r
1034      * Gets the day of the week for this date\r
1035      *\r
1036      * Gets the day of the week for this date (0=Sunday)\r
1037      *\r
1038      * @access public\r
1039      * @return int the day of the week (0=Sunday)\r
1040      */\r
1041     function getDayOfWeek()\r
1042     {\r
1043         return Date_Calc::dayOfWeek($this->day, $this->month, $this->year);\r
1044     }\r
1045 \r
1046     // }}}\r
1047     // {{{ getWeekOfYear()\r
1048 \r
1049     /**\r
1050      * Gets the week of the year for this date\r
1051      *\r
1052      * Gets the week of the year for this date\r
1053      *\r
1054      * @access public\r
1055      * @return int the week of the year\r
1056      */\r
1057     function getWeekOfYear()\r
1058     {\r
1059         return Date_Calc::weekOfYear($this->day, $this->month, $this->year);\r
1060     }\r
1061 \r
1062     // }}}\r
1063     // {{{ getQuarterOfYear()\r
1064 \r
1065     /**\r
1066      * Gets the quarter of the year for this date\r
1067      *\r
1068      * Gets the quarter of the year for this date\r
1069      *\r
1070      * @access public\r
1071      * @return int the quarter of the year (1-4)\r
1072      */\r
1073     function getQuarterOfYear()\r
1074     {\r
1075         return Date_Calc::quarterOfYear($this->day, $this->month, $this->year);\r
1076     }\r
1077 \r
1078     // }}}\r
1079     // {{{ getDaysInMonth()\r
1080 \r
1081     /**\r
1082      * Gets number of days in the month for this date\r
1083      *\r
1084      * Gets number of days in the month for this date\r
1085      *\r
1086      * @access public\r
1087      * @return int number of days in this month\r
1088      */\r
1089     function getDaysInMonth()\r
1090     {\r
1091         return Date_Calc::daysInMonth($this->month, $this->year);\r
1092     }\r
1093 \r
1094     // }}}\r
1095     // {{{ getWeeksInMonth()\r
1096 \r
1097     /**\r
1098      * Gets the number of weeks in the month for this date\r
1099      *\r
1100      * Gets the number of weeks in the month for this date\r
1101      *\r
1102      * @access public\r
1103      * @return int number of weeks in this month\r
1104      */\r
1105     function getWeeksInMonth()\r
1106     {\r
1107         return Date_Calc::weeksInMonth($this->month, $this->year);\r
1108     }\r
1109 \r
1110     // }}}\r
1111     // {{{ getDayName()\r
1112 \r
1113     /**\r
1114      * Gets the full name or abbriviated name of this weekday\r
1115      *\r
1116      * Gets the full name or abbriviated name of this weekday\r
1117      *\r
1118      * @access public\r
1119      * @param boolean $abbr abbrivate the name\r
1120      * @return string name of this day\r
1121      */\r
1122     function getDayName($abbr = false, $length = 3)\r
1123     {\r
1124         if ($abbr) {\r
1125             return Date_Calc::getWeekdayAbbrname($this->day, $this->month, $this->year, $length);\r
1126         } else {\r
1127             return Date_Calc::getWeekdayFullname($this->day, $this->month, $this->year);\r
1128         }\r
1129     }\r
1130 \r
1131     // }}}\r
1132     // {{{ getMonthName()\r
1133 \r
1134     /**\r
1135      * Gets the full name or abbriviated name of this month\r
1136      *\r
1137      * Gets the full name or abbriviated name of this month\r
1138      *\r
1139      * @access public\r
1140      * @param boolean $abbr abbrivate the name\r
1141      * @return string name of this month\r
1142      */\r
1143     function getMonthName($abbr = false)\r
1144     {\r
1145         if ($abbr) {\r
1146             return Date_Calc::getMonthAbbrname($this->month);\r
1147         } else {\r
1148             return Date_Calc::getMonthFullname($this->month);\r
1149         }\r
1150     }\r
1151 \r
1152     // }}}\r
1153     // {{{ getNextDay()\r
1154 \r
1155     /**\r
1156      * Get a Date object for the day after this one\r
1157      *\r
1158      * Get a Date object for the day after this one.\r
1159      * The time of the returned Date object is the same as this time.\r
1160      *\r
1161      * @access public\r
1162      * @return object Date Date representing the next day\r
1163      */\r
1164     function getNextDay()\r
1165     {\r
1166         $day = Date_Calc::nextDay($this->day, $this->month, $this->year, "%Y-%m-%d");\r
1167         $date = sprintf("%s %02d:%02d:%02d", $day, $this->hour, $this->minute, $this->second);\r
1168         $newDate = new Date();\r
1169         $newDate->setDate($date);\r
1170         return $newDate;\r
1171     }\r
1172 \r
1173     // }}}\r
1174     // {{{ getPrevDay()\r
1175 \r
1176     /**\r
1177      * Get a Date object for the day before this one\r
1178      *\r
1179      * Get a Date object for the day before this one.\r
1180      * The time of the returned Date object is the same as this time.\r
1181      *\r
1182      * @access public\r
1183      * @return object Date Date representing the previous day\r
1184      */\r
1185     function getPrevDay()\r
1186     {\r
1187         $day = Date_Calc::prevDay($this->day, $this->month, $this->year, "%Y-%m-%d");\r
1188         $date = sprintf("%s %02d:%02d:%02d", $day, $this->hour, $this->minute, $this->second);\r
1189         $newDate = new Date();\r
1190         $newDate->setDate($date);\r
1191         return $newDate;\r
1192     }\r
1193 \r
1194     // }}}\r
1195     // {{{ getNextWeekday()\r
1196 \r
1197     /**\r
1198      * Get a Date object for the weekday after this one\r
1199      *\r
1200      * Get a Date object for the weekday after this one.\r
1201      * The time of the returned Date object is the same as this time.\r
1202      *\r
1203      * @access public\r
1204      * @return object Date Date representing the next weekday\r
1205      */\r
1206     function getNextWeekday()\r
1207     {\r
1208         $day = Date_Calc::nextWeekday($this->day, $this->month, $this->year, "%Y-%m-%d");\r
1209         $date = sprintf("%s %02d:%02d:%02d", $day, $this->hour, $this->minute, $this->second);\r
1210         $newDate = new Date();\r
1211         $newDate->setDate($date);\r
1212         return $newDate;\r
1213     }\r
1214 \r
1215     // }}}\r
1216     // {{{ getPrevWeekday()\r
1217 \r
1218     /**\r
1219      * Get a Date object for the weekday before this one\r
1220      *\r
1221      * Get a Date object for the weekday before this one.\r
1222      * The time of the returned Date object is the same as this time.\r
1223      *\r
1224      * @access public\r
1225      * @return object Date Date representing the previous weekday\r
1226      */\r
1227     function getPrevWeekday()\r
1228     {\r
1229         $day = Date_Calc::prevWeekday($this->day, $this->month, $this->year, "%Y-%m-%d");\r
1230         $date = sprintf("%s %02d:%02d:%02d", $day, $this->hour, $this->minute, $this->second);\r
1231         $newDate = new Date();\r
1232         $newDate->setDate($date);\r
1233         return $newDate;\r
1234     }\r
1235 \r
1236     // }}}\r
1237     // {{{ getYear()\r
1238 \r
1239     /**\r
1240      * Returns the year field of the date object\r
1241      *\r
1242      * Returns the year field of the date object\r
1243      *\r
1244      * @access public\r
1245      * @return int the year\r
1246      */\r
1247     function getYear()\r
1248     {\r
1249         return (int)$this->year;\r
1250     }\r
1251 \r
1252     // }}}\r
1253     // {{{ getMonth()\r
1254 \r
1255     /**\r
1256      * Returns the month field of the date object\r
1257      *\r
1258      * Returns the month field of the date object\r
1259      *\r
1260      * @access public\r
1261      * @return int the month\r
1262      */\r
1263     function getMonth()\r
1264     {\r
1265         return (int)$this->month;\r
1266     }\r
1267 \r
1268     // }}}\r
1269     // {{{ getDay()\r
1270 \r
1271     /**\r
1272      * Returns the day field of the date object\r
1273      *\r
1274      * Returns the day field of the date object\r
1275      *\r
1276      * @access public\r
1277      * @return int the day\r
1278      */\r
1279     function getDay()\r
1280     {\r
1281         return (int)$this->day;\r
1282     }\r
1283 \r
1284     // }}}\r
1285     // {{{ getHour()\r
1286 \r
1287     /**\r
1288      * Returns the hour field of the date object\r
1289      *\r
1290      * Returns the hour field of the date object\r
1291      *\r
1292      * @access public\r
1293      * @return int the hour\r
1294      */\r
1295     function getHour()\r
1296     {\r
1297         return $this->hour;\r
1298     }\r
1299 \r
1300     // }}}\r
1301     // {{{ getMinute()\r
1302 \r
1303     /**\r
1304      * Returns the minute field of the date object\r
1305      *\r
1306      * Returns the minute field of the date object\r
1307      *\r
1308      * @access public\r
1309      * @return int the minute\r
1310      */\r
1311     function getMinute()\r
1312     {\r
1313         return $this->minute;\r
1314     }\r
1315 \r
1316     // }}}\r
1317     // {{{ getSecond()\r
1318 \r
1319     /**\r
1320      * Returns the second field of the date object\r
1321      *\r
1322      * Returns the second field of the date object\r
1323      *\r
1324      * @access public\r
1325      * @return int the second\r
1326      */\r
1327     function getSecond()\r
1328     {\r
1329          return $this->second;\r
1330     }\r
1331 \r
1332     // }}}\r
1333     // {{{ setYear()\r
1334 \r
1335     /**\r
1336      * Set the year field of the date object\r
1337      *\r
1338      * Set the year field of the date object, invalid years (not 0-9999) are set to 0.\r
1339      *\r
1340      * @access public\r
1341      * @param int $y the year\r
1342      */\r
1343     function setYear($y)\r
1344     {\r
1345         if ($y < 0 || $y > 9999) {\r
1346             $this->year = 0;\r
1347         } else {\r
1348             $this->year = $y;\r
1349         }\r
1350     }\r
1351 \r
1352     // }}}\r
1353     // {{{ setMonth()\r
1354 \r
1355     /**\r
1356      * Set the month field of the date object\r
1357      *\r
1358      * Set the month field of the date object, invalid months (not 1-12) are set to 1.\r
1359      *\r
1360      * @access public\r
1361      * @param int $m the month\r
1362      */\r
1363     function setMonth($m)\r
1364     {\r
1365         if ($m < 1 || $m > 12) {\r
1366             $this->month = 1;\r
1367         } else {\r
1368             $this->month = $m;\r
1369         }\r
1370     }\r
1371 \r
1372     // }}}\r
1373     // {{{ setDay()\r
1374 \r
1375     /**\r
1376      * Set the day field of the date object\r
1377      *\r
1378      * Set the day field of the date object, invalid days (not 1-31) are set to 1.\r
1379      *\r
1380      * @access public\r
1381      * @param int $d the day\r
1382      */\r
1383     function setDay($d)\r
1384     {\r
1385         if ($d > 31 || $d < 1) {\r
1386             $this->day = 1;\r
1387         } else {\r
1388             $this->day = $d;\r
1389         }\r
1390     }\r
1391 \r
1392     // }}}\r
1393     // {{{ setHour()\r
1394 \r
1395     /**\r
1396      * Set the hour field of the date object\r
1397      *\r
1398      * Set the hour field of the date object in 24-hour format.\r
1399      * Invalid hours (not 0-23) are set to 0.\r
1400      *\r
1401      * @access public\r
1402      * @param int $h the hour\r
1403      */\r
1404     function setHour($h)\r
1405     {\r
1406         if ($h > 23 || $h < 0) {\r
1407             $this->hour = 0;\r
1408         } else {\r
1409             $this->hour = $h;\r
1410         }\r
1411     }\r
1412 \r
1413     // }}}\r
1414     // {{{ setMinute()\r
1415 \r
1416     /**\r
1417      * Set the minute field of the date object\r
1418      *\r
1419      * Set the minute field of the date object, invalid minutes (not 0-59) are set to 0.\r
1420      *\r
1421      * @access public\r
1422      * @param int $m the minute\r
1423      */\r
1424     function setMinute($m)\r
1425     {\r
1426         if ($m > 59 || $m < 0) {\r
1427             $this->minute = 0;\r
1428         } else {\r
1429             $this->minute = $m;\r
1430         }\r
1431     }\r
1432 \r
1433     // }}}\r
1434     // {{{ setSecond()\r
1435 \r
1436     /**\r
1437      * Set the second field of the date object\r
1438      *\r
1439      * Set the second field of the date object, invalid seconds (not 0-59) are set to 0.\r
1440      *\r
1441      * @access public\r
1442      * @param int $s the second\r
1443      */\r
1444     function setSecond($s) {\r
1445         if ($s > 59 || $s < 0) {\r
1446             $this->second = 0;\r
1447         } else {\r
1448             $this->second = $s;\r
1449         }\r
1450     }\r
1451 \r
1452     // }}}\r
1453 }\r
1454 \r
1455 // }}}\r
1456 \r
1457 /*\r
1458  * Local variables:\r
1459  * mode: php\r
1460  * tab-width: 4\r
1461  * c-basic-offset: 4\r
1462  * c-hanging-comment-ender-p: nil\r
1463  * End:\r
1464  */\r
1465 ?>