Source for file Date.class.php

Documentation is available at Date.class.php

  1. <?php
  2. /**
  3.  * Gumbo Library Framework
  4.  *
  5.  * LICENSE
  6.  * This library is being released under the terms of the New BSD License.  A
  7.  * copy of the license is packaged with the software (LICENSE.txt).  If no
  8.  * copy is found, a copy of the license template can be found at:
  9.  * http://www.opensource.org/licenses/bsd-license.php
  10.  * 
  11.  * @category Gumbo
  12.  * @package Date
  13.  * @copyright Copyright (c) 2007, iBayou, Michael Luster
  14.  * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  15.  * @author Michael Luster <mluster79@yahoo.com>
  16.  * @link http://sourceforge.net/projects/phpgumbo
  17.  * @version 0.0.1
  18.  */
  19.  
  20. /**
  21.  * Date Class
  22.  *
  23.  * @category Gumbo
  24.  * @package Date
  25.  * @copyright Copyright (c) 2007, iBayou, Michael Luster
  26.  * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  27.  * @author Michael Luster <mluster79@yahoo.com>
  28.  * @link http://sourceforge.net/projects/phpgumbo
  29.  * @desc Date Class
  30.  * @version 0.0.1
  31.  */
  32.  
  33. gumbo_load ("Interface_Date");
  34. gumbo_load ("Number");
  35.  
  36. class Gumbo_Date implements Gumbo_Interface_Date {
  37.     
  38.     /** @var array $_orig original time stamp [year|month|day] */
  39.     private $_orig;
  40.     
  41.     /** @var int $_year */
  42.     private $_year = 2000;
  43.     /** @var int $_month */
  44.     private $_month = 1;
  45.     /** @var int $_day */
  46.     private $_day = 1;
  47.     /** @var int $_hour */
  48.     private $_hour = 0;
  49.     /** @var int $_minute */
  50.     private $_minute = 0;
  51.     /** @var int $_second */
  52.     private $_second = 0;
  53.     
  54.     /** @var bool $_holiday marks the date as a holiday */
  55.     private $_holiday = false;
  56.     
  57.     /** @var array $_facts general date facts concerning months */
  58.     private $_facts_month = array (1 => array ("name"=>"January", "days"=>31),
  59.                                     2 => array ("name"=>"February", "days"=>28),
  60.                                     3 => array ("name"=>"March", "days"=>31), 
  61.                                     4 => array ("name"=>"April", "days"=>30),
  62.                                     5 => array ("name"=>"May", "days"=>31), 
  63.                                     6 => array ("name"=>"June", "days"=>30),
  64.                                     7 => array ("name"=>"July", "days"=>31), 
  65.                                     8 => array ("name"=>"August", "days"=>31),
  66.                                     9 => array ("name"=>"September", "days"=>30), 
  67.                                     10 => array ("name"=>"October", "days"=>31),
  68.                                     11 => array ("name"=>"November", "days"=>30), 
  69.                                     12 => array ("name"=>"December", "days"=>31) );
  70.     
  71.     /** @var array $_facts_day days of the week facts */
  72.     private $_facts_day = array ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
  73.     
  74.     /** @var int MONTHS_IN_YEAR */
  75.     const MONTHS_IN_YEAR = 12;
  76.     
  77.     /** @var int DAYS_IN_YEAR */
  78.     const DAYS_IN_YEAR = 365;
  79.     /** @var int DAYS_IN_LEAP_YEAR */
  80.     const DAYS_IN_LEAP_YEAR = 366;
  81.     /** @var int DAYS_IN_WEEK */
  82.     const DAYS_IN_WEEK = 7;
  83.     
  84.     /** @var int WEEKS_IN_YEAR */
  85.     const WEEKS_IN_YEAR = 52;
  86.     
  87.     /** @var int HOURS_IN_DAY */
  88.     const HOURS_IN_DAY = 24;
  89.     /** @var int HOURS_IN_WEEK */
  90.     const HOURS_IN_WEEK = 168;
  91.     /** @var int HOURS_IN_YEAR */
  92.     const HOURS_IN_YEAR = 8760;
  93.     /** @var int HOURS_IN_LEAP_YEAR */
  94.     const HOURS_IN_LEAP_YEAR = 8784;
  95.     
  96.     /** @var int MINUTES_IN_HOUR */
  97.     const MINUTES_IN_HOUR = 60;
  98.     /** @var int MINUTES_IN_DAY */
  99.     const MINUTES_IN_DAY = 1440;
  100.     /** @var int MINUTES_IN_WEEK */
  101.     const MINUTES_IN_WEEK = 10080;
  102.     /** @var int MINUTES_IN_YEAR */
  103.     const MINUTES_IN_YEAR = 525600;
  104.     /** @var int MINUTES_IN_LEAP_YEAR */
  105.     const MINUTES_IN_LEAP_YEAR = 527040;
  106.     
  107.     /** @var int SECONDS_IN_MINUTE */
  108.     const SECONDS_IN_MINUTE = 60;
  109.     /** @var int SECONDS_IN_HOUR */
  110.     const SECONDS_IN_HOUR = 360;
  111.     /** @var int SECONDS_IN_DAY */
  112.     const SECONDS_IN_DAY = 8640;
  113.     /** @var int SECONDS_IN_WEEK */
  114.     const SECONDS_IN_WEEK = 60480;
  115.     /** @var int SECONDS_IN_YEAR */
  116.     const SECONDS_IN_YEAR = 3153600;
  117.     /** @var int SECONDS_IN_LEAP_YEAR */
  118.     const SECONDS_IN_LEAP_YEAR = 3162240;
  119.     
  120.     
  121.     
  122.     /**
  123.      * Constructor
  124.      * @param string|int$stamp full date stamp, or year value
  125.      * @param int $month 
  126.      * @param int $day 
  127.      * @param int $hour 
  128.      * @param int $minute 
  129.      * @param int $seconds 
  130.      */
  131.     public function __construct ($stamp, $month=null, $day=null, $hour=null, $minute=null, $seconds=null) {
  132.         if (is_string ($stamp) || strlen ($stamp > 4)) {
  133.             $this->_parse ($stamp);
  134.             return;
  135.         }
  136.         
  137.         if (is_numeric ($stamp) && strlen ($stamp) <= 4) { $this->setYear ($stamp); }
  138.         if (!is_null ($month) && (is_numeric ($month) || is_string ($month))) { $this->setMonth ($month); }
  139.         if (!is_null ($day) && is_numeric ($day)) { $this->setDay ($day); }
  140.         if (!is_null ($hour) && is_numeric ($hour)) { $this->setHour ($hour); }
  141.         if (!is_null ($minute) && is_numeric ($minute)) { $this->setMinute ($minute); }
  142.         if (!is_null ($seconds) && is_numeric ($seconds)) { $this->setSeconds ($seconds); }
  143.         
  144.         $this->_setOrigStamp ($this->getYear (), $this->getMonth (), $this->getDay (), $this->getHour (), $this->getMinute (), $this->getSecond ());
  145.     }
  146.     
  147.     
  148.     
  149.     /** STATIC METHODS **/
  150.     /**
  151.      * Checks if the current year is a Leap Year
  152.      * @param int $year 
  153.      * @return bool 
  154.      * @throws Gumbo_Exception
  155.      */
  156.     public static function isLeapYear ($year) {
  157.         try {
  158.             // verify precondition
  159.             if (!is_numeric ($year)) {
  160.                 throw new Gumbo_Exception ("Invalid Argument 'year:num' => {$year}:" . gettype ($year));
  161.             }
  162.             if ($year < 0) {
  163.                 throw new Gumbo_Exception ("Out Of Range 'year > 0' => {$year}");
  164.             }
  165.             
  166.             // leap year formula
  167.             if ($year % 4 != 0) {
  168.                 return false;
  169.             } elseif ($year % 400 == 0) {
  170.                 return true;
  171.             } elseif ($year % 100 == 0) {
  172.                 return false;
  173.             }
  174.             return true;
  175.         } catch (Gumbo_Exception $e) {
  176.             $e->setFunction (__METHOD__);
  177.             gumbo_trigger ($e);
  178.         }
  179.         return false;
  180.     }
  181.     
  182.     
  183.     
  184.     /** ACTION METHODS **/
  185.     /**
  186.      * Resets the state to the original time stamp
  187.      */
  188.     public function reset () {
  189.         $orig = $this->_getOrigStamp ();
  190.         $this->setDate ($orig ['year'], $orig ['month'], $orig ['day']);
  191.         $this->setTime ($orig ['hour'], $orig ['minute'], $orig ['second']);
  192.     }
  193.     
  194.     /**
  195.      * Sets the time to the zero hour
  196.      * @postcondition $hour=0
  197.      * @postcondition $minutes=0
  198.      * @postcondition $seconds=0
  199.      */
  200.     public function zeroHour () {
  201.         $this->setTime (0, 0, 0);
  202.     }
  203.     
  204.     /**
  205.      * Calculates the current Day of the Week
  206.      * @return int 
  207.      */
  208.     private function _calcDayOfWeek () {
  209.         $year = $this->getYear ();
  210.         $month = $this->getMonth ();
  211.         $day = $this->getDay ();
  212.         
  213.         $cent = floor ($year / 100);
  214.         $year %= 100;
  215.         
  216.         if ($month < 3) {
  217.             $month += 12;
  218.             if ($year > 0) { $year--; }
  219.         } else {
  220.             $year = 99;
  221.             $cent--;
  222.         }
  223.         
  224.         $wday = $day;
  225.         $wday += ((($month + 1) * 26) / 10);
  226.         $wday += $year + ($year / 4);
  227.         $wday += ($cent / 4) - ($cent * 2);
  228.         
  229.         if ($wday < 0) { $wday += 7; }
  230.         $wday %= 7;
  231.         if ($wday == 0) { $wday = 7; }
  232.         $wday--;
  233.         
  234.         return $wday;
  235.     }
  236.     
  237.     /**
  238.      * Calculates the Day of the Year
  239.      * @return int 
  240.      */
  241.     private function _calcDayOfYear () {
  242.         $month = $this->getMonth ();
  243.         $day = $this->getDay ();
  244.         
  245.         $count = 0;
  246.         for ($x = 1;$x < 13;$x++) {
  247.             if ($x == $month) { break; }
  248.             $count += $this->totalDays ($month);
  249.         }
  250.         $count += $day;
  251.         
  252.         return $count;
  253.     }
  254.     
  255.     /**
  256.      * Calculates the Week of the Year
  257.      * @return int 
  258.      */
  259.     private function _calcWeekOfYear () {
  260.         $day = $this->_calcDayOfYear ();
  261.         return floor ($day / 7);
  262.     }
  263.     
  264.     /**
  265.      * Increases the Year by number
  266.      * @precondition $num > 0
  267.      * @param int $num 
  268.      * @throws Gumbo_Exception
  269.      */
  270.     public function nextYear ($num=1) {
  271.         try {
  272.             if (!is_numeric ($num)) {
  273.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  274.             }
  275.             if ($num < 1) {
  276.                 throw new Gumbo_Exception ("Argument Out of Range, Must Be Greater Than 0");
  277.             }
  278.             $num = (int) $num;
  279.         } catch (Gumbo_Exception $e) {
  280.             $e->setFunction (__METHOD__);
  281.             gumbo_trigger ($e);
  282.             $num = 1;
  283.         }
  284.         
  285.         if ($num > 1) {
  286.             $this->_change ($num, __FUNCTION__);
  287.             return;
  288.         }
  289.         
  290.         $this->_year++;
  291.     }
  292.     
  293.     /**
  294.      * Increases the Month by number.
  295.      * @precondition $num > 0
  296.      * @param int $num 
  297.      * @throws Gumbo_Exception
  298.      */
  299.     public function nextMonth ($num=1) {
  300.         try {
  301.             if (!is_numeric ($num)) {
  302.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  303.             }
  304.             if ($num < 1) {
  305.                 throw new Gumbo_Exception ("Argument Out of Range, Must Be Greater Than 0");
  306.             }
  307.             $num = (int) $num;
  308.         } catch (Gumbo_Exception $e) {
  309.             $e->setFunction (__METHOD__);
  310.             gumbo_trigger ($e);
  311.             $num = 1;
  312.         }
  313.         
  314.         if ($num > 1) {
  315.             $this->_change ($num, __FUNCTION__);
  316.             return;
  317.         }
  318.         
  319.         $this->_month++;
  320.         if ($this->getMonth () >= 13) {
  321.             $this->setMonth (1);
  322.             $this->nextYear ();
  323.             $this->setDay ($this->getDay ());
  324.         }
  325.     }
  326.     
  327.     /**
  328.      * Increases the Week
  329.      * @precondition $num > 0
  330.      * @param int $num 
  331.      * @throws Gumbo_Exception
  332.      */
  333.     public function nextWeek ($num=1) {
  334.         try {
  335.             if (!is_numeric ($num)) {
  336.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  337.             }
  338.             if ($num < 1) {
  339.                 throw new Gumbo_Exception ("Argument Out of Range, Must Be Greater Than 0");
  340.             }
  341.             $num = (int) $num;
  342.         } catch (Gumbo_Exception $e) {
  343.             $e->setFunction (__METHOD__);
  344.             gumbo_trigger ($e);
  345.             $num = 1;
  346.         }
  347.         
  348.         if ($num > 1) {
  349.             $this->_change ($num, __FUNCTION__);
  350.             return;
  351.         }
  352.         
  353.         $this->nextDay (7);
  354.     }
  355.     
  356.     /**
  357.      * Increases the Day
  358.      * @precondition $num > 0
  359.      * @param int $num 
  360.      * @throws Gumbo_Exception
  361.      */
  362.     public function nextDay ($num=1) {
  363.         try {
  364.             if (!is_numeric ($num)) {
  365.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  366.             }
  367.             if ($num < 1) {
  368.                 throw new Gumbo_Exception ("Argument Out of Range, Must Be Greater Than 0");
  369.             }
  370.             $num = (int) $num;
  371.         } catch (Gumbo_Exception $e) {
  372.             $e->setFunction (__METHOD__);
  373.             gumbo_trigger ($e);
  374.             $num = 1;
  375.         }
  376.         
  377.         if ($num > 1) {
  378.             $this->_change ($num, __FUNCTION__);
  379.             return;
  380.         }
  381.         
  382.         $this->_day++;
  383.         if ($this->getDay () > $this->totalDays ($this->getMonth ())) {
  384.             // checking for a leap year
  385.             if ($this->getMonth () == 2 && $this->isLeapYear () && $this->getDay () == 29) {
  386.                 return;
  387.             }
  388.             
  389.             $this->setDay (1);
  390.             $this->nextMonth ();
  391.         }
  392.     }
  393.     
  394.     /**
  395.      * Increases the Hour
  396.      * @precondition $num > 0
  397.      * @param int $num 
  398.      * @throws Gumbo_Exception
  399.      */
  400.     public function nextHour ($num=1) {
  401.         try {
  402.             if (!is_numeric ($num)) {
  403.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  404.             }
  405.             if ($num < 1) {
  406.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  407.             }
  408.             $num = (int) $num;
  409.         } catch (Gumbo_Exception $e) {
  410.             $e->setFunction (__METHOD__);
  411.             gumbo_trigger ($e);
  412.             $num = 1;
  413.         }
  414.         
  415.         if ($num > 1) {
  416.             $this->_change ($num, __FUNCTION__);
  417.             return;
  418.         }
  419.         
  420.         $this->_hour++;
  421.         if ($this->getHour () > 23) {
  422.             $this->setHour (0);
  423.             $this->nextDay ();
  424.         }
  425.     }
  426.     
  427.     /**
  428.      * Increases the Minutes
  429.      * @precondition $num > 0
  430.      * @param int $num 
  431.      * @throws Gumbo_Exception
  432.      */
  433.     public function nextMinute ($num=1) {
  434.         try {
  435.             if (!is_numeric ($num)) {
  436.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  437.             }
  438.             if ($num < 1) {
  439.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  440.             }
  441.             $num = (int) $num;
  442.         } catch (Gumbo_Exception $e) {
  443.             $e->setFunction (__METHOD__);
  444.             gumbo_trigger ($e);
  445.             $num = 1;
  446.         }
  447.         
  448.         if ($num > 1) {
  449.             $this->_change ($num, __FUNCTION__);
  450.             return;
  451.         }
  452.         
  453.         $this->_minute++;
  454.         if ($this->getMinute () > 59) {
  455.             $this->setMinute (0);
  456.             $this->nextHour ();
  457.         }
  458.     }
  459.     
  460.     /**
  461.      * Increases the Seconds
  462.      * @precondition $num > 0
  463.      * @param int $num 
  464.      * @throws Gumbo_Exception
  465.      */
  466.     public function nextSecond ($num=1) {
  467.         try {
  468.             if (!is_numeric ($num)) {
  469.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  470.             }
  471.             if ($num < 1) {
  472.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  473.             }
  474.             $num = (int) $num;
  475.         } catch (Gumbo_Exception $e) {
  476.             $e->setFunction (__METHOD__);
  477.             gumbo_trigger ($e);
  478.             $num = 1;
  479.         }
  480.         
  481.         if ($num > 1) {
  482.             $this->_change ($num, __FUNCTION__);
  483.             return;
  484.         }
  485.         
  486.         $this->_second++;
  487.         if ($this->getSecond () > 59) {
  488.             $this->setSeconds (0);
  489.             $this->nextMinute ();
  490.         }
  491.     }
  492.     
  493.     /**
  494.      * Decreases the Year
  495.      * @precondition $num > 0
  496.      * @param int $num 
  497.      * @throws Gumbo_Exception
  498.      */
  499.     public function prevYear ($num=1) {
  500.         try {
  501.             if (!is_numeric ($num)) {
  502.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  503.             }
  504.             if ($num < 1) {
  505.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  506.             }
  507.             $num = (int) $num;
  508.         } catch (Gumbo_Exception $e) {
  509.             $e->setFunction (__METHOD__);
  510.             gumbo_trigger ($e);
  511.             $num = 1;
  512.         }
  513.         
  514.         if ($num > 1) {
  515.             $this->_change ($num, __FUNCTION__);
  516.             return;
  517.         }
  518.         
  519.         if ($this->getYear () == 0) { return; }
  520.         $this->_year--;
  521.     }
  522.     
  523.     /**
  524.      * Decreases the Month
  525.      * @precondition $num > 0
  526.      * @param int $num 
  527.      * @throws Gumbo_Exception
  528.      */
  529.     public function prevMonth ($num=1) {
  530.         try {
  531.             if (!is_numeric ($num)) {
  532.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  533.             }
  534.             if ($num < 1) {
  535.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  536.             }
  537.             $num = (int) $num;
  538.         } catch (Gumbo_Exception $e) {
  539.             $e->setFunction (__METHOD__);
  540.             gumbo_trigger ($e);
  541.             $num = 1;
  542.         }
  543.         
  544.         if ($num > 1) {
  545.             $this->_change ($num, __FUNCTION__);
  546.             return;
  547.         }
  548.         
  549.         $this->_month--;
  550.         if ($this->getMonth () < 1) {
  551.             $this->setMonth (12);
  552.             $this->prevYear ();
  553.         }
  554.     }
  555.     
  556.     /**
  557.      * Decreases the Week
  558.      * @precondition $num > 0
  559.      * @param int $num 
  560.      * @throws Gumbo_Exception
  561.      */
  562.     public function prevWeek ($num=1) {
  563.         try {
  564.             if (!is_numeric ($num)) {
  565.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  566.             }
  567.             if ($num < 1) {
  568.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  569.             }
  570.             $num = (int) $num;
  571.         } catch (Gumbo_Exception $e) {
  572.             $e->setFunction (__METHOD__);
  573.             gumbo_trigger ($e);
  574.             $num = 1;
  575.         }
  576.         
  577.         if ($num > 1) {
  578.             $this->_change ($num, __FUNCTION__);
  579.             return;
  580.         }
  581.         
  582.         $this->prevDay (7);
  583.     }
  584.     
  585.     /**
  586.      * Decreases the Day
  587.      * @precondition $num > 0
  588.      * @param int $num 
  589.      * @throws Gumbo_Exception
  590.      */
  591.     public function prevDay ($num=1) {
  592.         try {
  593.             if (!is_numeric ($num)) {
  594.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  595.             }
  596.             if ($num < 1) {
  597.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  598.             }
  599.             $num = (int) $num;
  600.         } catch (Gumbo_Exception $e) {
  601.             $e->setFunction (__METHOD__);
  602.             gumbo_trigger ($e);
  603.             $num = 1;
  604.         }
  605.         
  606.         if ($num > 1) {
  607.             $this->_change ($num, __FUNCTION__);
  608.             return;
  609.         }
  610.         
  611.         $this->_day--;
  612.         if ($this->getDay () < 1) {
  613.             $this->prevMonth ();
  614.             $this->setDay ($this->totalDays ($this->getMonth ()));
  615.             
  616.             // checking for February leap year
  617.             if ($this->getMonth () == 2 && $this->isLeapYear () && $this->getDay () == 28) {
  618.                 $this->setDay (29);
  619.             }
  620.         }
  621.     }
  622.     
  623.     /**
  624.      * Decreases the Hour
  625.      * @precondition $num > 0
  626.      * @param int $num 
  627.      * @throws Gumbo_Exception
  628.      */
  629.     public function prevHour ($num=1) {
  630.         try {
  631.             if (!is_numeric ($num)) {
  632.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  633.             }
  634.             if ($num < 1) {
  635.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  636.             }
  637.             $num = (int) $num;
  638.         } catch (Gumbo_Exception $e) {
  639.             $e->setFunction (__METHOD__);
  640.             gumbo_trigger ($e);
  641.             $num = 1;
  642.         }
  643.         
  644.         if ($num > 1) {
  645.             $this->_change ($num, __FUNCTION__);
  646.             return;
  647.         }
  648.         
  649.         $this->_hour--;
  650.         if ($this->getHour () < 0) {
  651.             $this->setHour (23);
  652.             $this->prevDay ();
  653.         }
  654.     }
  655.     
  656.     /**
  657.      * Decreases the Minutes
  658.      * @precondition $num > 0
  659.      * @param int $num 
  660.      * @throws Gumbo_Exception
  661.      */
  662.     public function prevMinute ($num=1) {
  663.         try {
  664.             if (!is_numeric ($num)) {
  665.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  666.             }
  667.             if ($num < 1) {
  668.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  669.             }
  670.             $num = (int) $num;
  671.         } catch (Gumbo_Exception $e) {
  672.             $e->setFunction (__METHOD__);
  673.             gumbo_trigger ($e);
  674.             $num = 1;
  675.         }
  676.         
  677.         if ($num > 1) {
  678.             $this->_change ($num, __FUNCTION__);
  679.             return;
  680.         }
  681.         
  682.         $this->_minute--;
  683.         if ($this->getMinute () < 0) {
  684.             $this->setMinute (59);
  685.             $this->prevHour ();
  686.         }
  687.     }
  688.     
  689.     /**
  690.      * Decreases the Seconds
  691.      * @precondition $num > 0
  692.      * @param int $num 
  693.      * @throws Gumbo_Exception
  694.      */
  695.     public function prevSecond ($num=1) {
  696.         try {
  697.             if (!is_numeric ($num)) {
  698.                 throw new Gumbo_Exception ("Invalid Argument 'num:int' => {$num}:" . gettype ($num));
  699.             }
  700.             if ($num < 1) {
  701.                 throw new Gumbo_Exception ("Out of Range 'num > 0'");
  702.             }
  703.             $num = (int) $num;
  704.         } catch (Gumbo_Exception $e) {
  705.             $e->setFunction (__METHOD__);
  706.             gumbo_trigger ($e);
  707.             $num = 1;
  708.         }
  709.         
  710.         if ($num > 1) {
  711.             $this->_change ($num, __FUNCTION__);
  712.             return;
  713.         }
  714.         
  715.         $this->_second--;
  716.         if ($this->getSecond () < 0) {
  717.             $this->setSeconds (59);
  718.             $this->prevMinute ();
  719.         }
  720.     }
  721.     
  722.     
  723.     
  724.     /** MUTATOR METHODS **/
  725.     /**
  726.      * Sets the original time stamp
  727.      * @param int $year 
  728.      * @param int $month 
  729.      * @param int $day 
  730.      * @param int $hour 
  731.      * @param int $minute 
  732.      * @param int $second 
  733.      * @throws Gumbo_Exception
  734.      */
  735.     private function _setOrigStamp ($year, $month, $day, $hour, $minute, $second) {
  736.         try {
  737.             if (!is_int ($year)) {
  738.                 throw new Gumbo_Exception ("Invalid Argument 'year:int' => {$year}:" . gettype ($year));
  739.             }
  740.             if (!is_int ($month)) {
  741.                 throw new Gumbo_Exception ("Invalid Argument 'month:int' => {$month}:" . gettype ($month));
  742.             }
  743.             if (!is_int ($day)) {
  744.                 throw new Gumbo_Exception ("Invalid Argument 'day:int' => {$day}:" . gettype ($day));
  745.             }
  746.             if (!is_int ($hour)) {
  747.                 throw new Gumbo_Exception ("Invalid Argument 'hour:int' => {$hour}:" . gettype ($hour));
  748.             }
  749.             if (!is_int ($minute)) {
  750.                 throw new Gumbo_Exception ("Invalid Argument 'minute:int' => {$minute}:" . gettype ($minute));
  751.             }
  752.             if (!is_int ($second)) {
  753.                 throw new Gumbo_Exception ("Invalid Argument 'second:int' => {$second}:" . gettype ($second));
  754.             }
  755.             
  756.             $this->_orig ['year'] = $year;
  757.             $this->_orig ['month'] = $month;
  758.             $this->_orig ['day'] = $day;
  759.             $this->_orig ['hour'] = $hour;
  760.             $this->_orig ['minute'] = $minute;
  761.             $this->_orig ['second'] = $second;
  762.         } catch (Gumbo_Exception $e) {
  763.             $e->setFunction (__METHOD__);
  764.             gumbo_trigger ($e);
  765.         }
  766.     }
  767.     
  768.     /**
  769.      * Marks the Date as a Holiday
  770.      * @param bool $val 
  771.      * @throws Gumbo_Exception
  772.      */
  773.     public function setHoliday ($val) {
  774.         try {
  775.             if (!is_bool ($val)) {
  776.                 throw new Gumbo_Exception ("Invalid Argument 'val:bool' => {$val}:" . gettype ($val));
  777.             }
  778.             
  779.             $this->_holiday = $val;
  780.         } catch (Gumbo_Exception $e) {
  781.             $e->setFunction (__METHOD__);
  782.             gumbo_trigger ($e);
  783.         }
  784.     }
  785.     
  786.     /**
  787.      * Sets the Date values of the object
  788.      * @param int $year 
  789.      * @param int $month 
  790.      * @param int $day 
  791.      */
  792.     public function setDate ($year, $month, $day) {
  793.         $this->setYear ($year);
  794.         $this->setMonth ($month);
  795.         $this->setDay ($day);
  796.     }
  797.     
  798.     /**
  799.      * Sets the Time values of object
  800.      * @param int $hour 
  801.      * @param int $minutes 
  802.      * @param int $seconds 
  803.      */
  804.     public function setTime ($hour, $minutes, $seconds) {
  805.         $this->setHour ($hour);
  806.         $this->setMinute ($minutes);
  807.         $this->setSeconds ($seconds);
  808.     }
  809.     
  810.     /**
  811.      * Sets the Date by a stamp parsed down to yyyymmdd[hhmmss] format
  812.      * @param mixed $stamp 
  813.      * @throws Gumbo_Exception
  814.      */
  815.     public function setDateStamp ($stamp) {
  816.         try {
  817.             // verify precondition
  818.             if (!is_string ($stamp) && !is_numeric ($stamp)) {
  819.                 throw new Gumbo_Exception ("Invalid Argument 'stamp:int|str' => {$stamp}: " . gettype ($stamp));
  820.             }
  821.             
  822.             $this->_parse ($stamp);
  823.         } catch (Gumbo_Exception $e) {
  824.             $e->setFunction (__METHOD__);
  825.             gumbo_trigger ($e);
  826.         }
  827.     }
  828.     
  829.     /**
  830.      * Sets the Date by the UNIX Epoch
  831.      * @param int $time 
  832.      * @throws Gumbo_Exception
  833.      */
  834.     public function setDateEpoch ($time) {
  835.         try {
  836.             // verify precondition
  837.             if (!is_int ($time)) {
  838.                 throw new Gumbo_Exception ("Invalid Argument 'time:int' => {$time}:" . gettype ($time));
  839.             }
  840.             
  841.             $this->_parse (date ("YmdHis", $time));
  842.         } catch (Gumbo_Exception $e) {
  843.             $e->setFunction (__METHOD__);
  844.             gumbo_trigger ($e);
  845.         }
  846.     }
  847.     
  848.     /**
  849.      * Sets the Year
  850.      * @precondition $val > 0
  851.      * @param int $year 
  852.      * @throws Gumbo_Exception
  853.      */
  854.     public function setYear ($year) {
  855.         try {
  856.             // verify precondition
  857.             if (!is_numeric ($year)) {
  858.                 throw new Gumbo_Exception ("Invalid Argument 'year:int' => {$year}:" . gettype ($year));
  859.             }
  860.             if ($year <= 0) {
  861.                 throw new Gumbo_Exception ("Out Of Range 'year > 0' => {$year}");
  862.             }
  863.             
  864.             $this->_year = (int) $year;
  865.         } catch (Gumbo_Exception $e) {
  866.             $e->setFunction (__METHOD__);
  867.             gumbo_trigger ($e);
  868.         }
  869.     }
  870.     
  871.     /**
  872.      * Sets the Month
  873.      * 
  874.      * The value can be the numberical month, a three-letter abbreviation of the
  875.      * month name, or the full name.
  876.      * 
  877.      * @precondition if int, 0 < $val < 13
  878.      * @param int|string$month 
  879.      * @throws Gumbo_Exception
  880.      */
  881.     public function setMonth ($month) {
  882.         try {
  883.             // verify precondition
  884.             if (!is_numeric ($month) && !is_string ($month)) {
  885.                 throw new Gumbo_Exception ("Invalid Argument 'month:num|str' => {$month}:" . gettype ($month));
  886.             }
  887.             
  888.             // parse string months
  889.             if (is_string ($month)) {
  890.                 $month = strtolower ($month);
  891.                 foreach ($this->getMonthFacts () as $key=>$val) {
  892.                     if (substr ($month, 0, 3) == substr (strtolower ($val ['name']), 0, 3)) {
  893.                         $month = $key;
  894.                         break;
  895.                     }
  896.                 }
  897.                 if (!is_numeric ($month)) {
  898.                     throw new Gumbo_Exception ("Invalid Argument 'month:num|str' => {$month}:" . gettype ($month));
  899.                 }
  900.             }
  901.             
  902.             // verify precondtions
  903.             if ($month <= 0 || $month >= 13) {
  904.                 throw new Gumbo_Exception ("Out Of Range '0 < month < 13' => {$month}");
  905.             }
  906.             
  907.             $this->_month = (int) $month;
  908.         } catch (Gumbo_Exception $e) {
  909.             $e->setFunction (__METHOD__);
  910.             gumbo_trigger ($e);
  911.         }
  912.     }
  913.     
  914.     /**
  915.      * Sets the Day
  916.      * @precondition 0 < $val <= 31
  917.      * @param int $day 
  918.      * @throws Gumbo_Exception
  919.      */
  920.     public function setDay ($day) {
  921.         try {
  922.             // verify precondition
  923.             if (!is_numeric ($day)) {
  924.                 throw new Gumbo_Exception ("Invalid Argument 'day:num' => {$day}:" . gettype ($day));
  925.             }
  926.             if ($day <= 0 || $day > 31) {
  927.                 throw new Gumbo_Exception ("Out Of Range '0 < day < 32' => {$day}");
  928.             }
  929.             $day = (int) $day;
  930.             
  931.             // check for maximum day on current month
  932.             $tmp = $this->getMonthFacts ();
  933.             $num = $tmp [$this->getMonth ()]['days'];
  934.             if ($day > $num) {
  935.                 $day = $num;
  936.                 if (Date::isLeapYear ($this->getYear ()) && $this->getMonth () == 2) {
  937.                     $day = 29;
  938.                 }
  939.             }
  940.             
  941.             $this->_day = (int) $day;
  942.         } catch (Gumbo_Exception $e) {
  943.             $e->setFunction (__METHOD__);
  944.             gumbo_trigger ($e);
  945.         }
  946.     }
  947.     
  948.     /**
  949.      * Sets the Hour
  950.      * @precondition 0 <= $val < 24
  951.      * @param int $hour 
  952.      * @throws Gumbo_Exception
  953.      */
  954.     public function setHour ($hour) {
  955.         try {
  956.             // verify precondition
  957.             if (!is_numeric ($hour)) {
  958.                 throw new Gumbo_Exception ("Invalid Argument 'hour:num' => {$hour}:" . gettype ($hour));
  959.             }
  960.             if ($hour < 0 || $hour >= 24) {
  961.                 throw new Gumbo_Exception ("Out Of Range '0 <= hour < 24' => {$hour}");
  962.             }
  963.             
  964.             $this->_hour = (int) $hour;
  965.         } catch (Gumbo_Exception $e) {
  966.             $e->setFunction (__METHOD__);
  967.             gumbo_trigger ($e);
  968.         }
  969.     }
  970.     
  971.     /**
  972.      * Sets the Minute
  973.      * @precondition 0 <= $val < 60
  974.      * @param int $min 
  975.      * @throws Gumbo_Exception
  976.      */
  977.     public function setMinute ($min) {
  978.         try {
  979.             // verify preconditions
  980.             if (!is_numeric ($min)) {
  981.                 throw new Gumbo_Exception ("Invalid Argument 'min:num' => {$min}:" . gettype ($min));
  982.             }
  983.             if ($min < 0 || $min >= 60) {
  984.                 throw new Gumbo_Exception ("Out Of Range '0 <= min < 60' => {$min}");
  985.             }
  986.             
  987.             $this->_minute = (int) $min;
  988.         } catch (Gumbo_Exception $e) {
  989.             $e->setFunction (__METHOD__);
  990.             gumbo_trigger ($e);
  991.         }
  992.     }
  993.     
  994.     /**
  995.      * Sets the Seconds
  996.      * @precondition 0 <= $val < 60
  997.      * @param int $sec 
  998.      * @throws Gumbo_Exception
  999.      */
  1000.     public function setSeconds ($sec) {
  1001.         try {
  1002.             // verify precondition
  1003.             if (!is_numeric ($sec)) {
  1004.                 throw new Gumbo_Exception ("Invalid Argument 'sec:num' => {$sec}:" . gettype ($sec));
  1005.             }
  1006.             if ($sec < 0 || $sec >= 60) {
  1007.                 throw new Gumbo_Exception ("Out Of Range '0 <= sec < 60' => {$sec}");
  1008.             }
  1009.             
  1010.             $this->_second = (int) $sec;
  1011.         } catch (Gumbo_Exception $e) {
  1012.             $e->setFunction (__METHOD__);
  1013.             gumbo_trigger ($e);
  1014.         }
  1015.     }
  1016.     
  1017.     /**
  1018.      * Parses the timestamp into Date components
  1019.      * @param string|int$stamp 
  1020.      */
  1021.     private function _parse ($stamp) {
  1022.         $stamp = ereg_replace ("([^0-9]*)", "", $stamp);
  1023.         
  1024.         $this->setYear (substr ($stamp, 0, 4));
  1025.         $this->setMonth (substr ($stamp, 4, 2));
  1026.         $this->setDay (substr ($stamp, 6, 2));
  1027.         $this->setHour (substr ($stamp, 8, 2));
  1028.         $this->setMinute (substr ($stamp, 10, 2));
  1029.         $this->setSeconds (substr ($stamp, 12, 2));
  1030.     }
  1031.     
  1032.     /**
  1033.      * Changes the particular element by the supplied number
  1034.      * @param int $num number to increase/decrease
  1035.      * @param string $method Date method to call
  1036.      * @throws Gumbo_Exception
  1037.      */
  1038.     private function _change ($num, $method) {
  1039.         try {
  1040.             // verify precondition
  1041.             if (!is_numeric ($num)) {
  1042.                 throw new Gumbo_Exception ("Invalid Argument 'num:num' => {$num}:" . gettype ($num));
  1043.             }
  1044.             if (!is_string ($method)) {
  1045.                 throw new Gumbo_Exception ("Invalid Argument 'method:str' => {$method}:" . gettype ($method));
  1046.             }
  1047.             if (!method_exists ($this, $method)) {
  1048.                 throw new Gumbo_Exception ("Method Does Not Exist '{$method}'");
  1049.             }
  1050.             $num = abs ($num);
  1051.             
  1052.             for ($x = 0;$x < $num;$x++) {
  1053.                 $this->$method ();
  1054.             }
  1055.         } catch (Gumbo_Exception $e) {
  1056.             $e->setFunction (__METHOD__);
  1057.             gumbo_trigger ($e);
  1058.         }
  1059.     }
  1060.     
  1061.     
  1062.     
  1063.     /** ACCESSOR METHODS **/
  1064.     /**
  1065.      * Returns the original time stamp
  1066.      * @return array as [year|month|day]
  1067.      */
  1068.     private function _getOrigStamp () {
  1069.         return $this->_orig;
  1070.     }
  1071.     
  1072.     /**
  1073.      * Returns a Date string in predefined format
  1074.      * Format Codes:
  1075.      * - 0 => yyyy-mm-dd hh:mm:ss (MySQL DATETIME)
  1076.      * - 1 => yyyymm
  1077.      * - 2 => yyyymmdd
  1078.      * - 3 => yyyymmddhh
  1079.      * - 4 => yyyymmddhhmm
  1080.      * - 5 => yyyymmddhhmmss
  1081.      * - 6 => UNIX EPOCH
  1082.      * 
  1083.      * To use more complex combinations, use a combination of the
  1084.      * getDate() and getTime() methods.
  1085.      * 
  1086.      * @param int $format format code
  1087.      * @return int|string
  1088.      * @throws Gumbo_Exception
  1089.      */
  1090.     public function get ($format=null) {
  1091.         try {
  1092.             // verify precondition
  1093.             if (!is_null ($format) && !is_numeric ($format)) {
  1094.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1095.             }
  1096.             
  1097.             if (is_null ($format)) { $format = 0; }
  1098.             $format = (int) $format;
  1099.             
  1100.             if ($format < 0 || $format > 6) {
  1101.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 6'");
  1102.             }
  1103.         } catch (Gumbo_Exception $e) {
  1104.             $e->setFunction (__METHOD__);
  1105.             gumbo_trigger ($e);
  1106.             $format = 0;
  1107.         }
  1108.         
  1109.         $txt = false;
  1110.         switch ($format) {
  1111.             case 1 : $txt = $this->getDate (1); break;
  1112.             case 2 : $txt = $this->getDate (2); break;
  1113.             case 3 : $txt = $this->getDate (2) . $this->getTime (1); break;
  1114.             case 4 : $txt = $this->getDate (2) . $this->getTime (2); break;
  1115.             case 5 : $txt = $this->getDate (2) . $this->getTime (3); break;
  1116.             case 6 : $txt = mktime ($this->getHour (), $this->getMinute (), $this->getSecond (), $this->getMonth (), $this->getDay (), $this->getYear ()); break;
  1117.             default : $txt = $this->getDate () . " " . $this->getTime (); break;
  1118.         }
  1119.         return $txt;
  1120.     }
  1121.     
  1122.     /**
  1123.      * Returns a formatted Date string
  1124.      * Date Formats:
  1125.      * - 0 => yyyy-mm-dd (default)
  1126.      * - 1 => yyyymm
  1127.      * - 2 => yyyymmdd
  1128.      * - 3 => mm/dd/yyyy
  1129.      * - 4 => [m]m/[d]d/yyyy
  1130.      * - 5 => Mon [d]d[suffix], yyyy
  1131.      * - 6 => Month [d]d[suffix], yyyy
  1132.      * - 7 => Day, [d]d Mon yyyy
  1133.      * 
  1134.      * The method also uses the date() and strftime() functions.  The format
  1135.      * would have to be a string representing values the function will parse.
  1136.      * If the percent sign (%) is found, it will use strftime(), else it will
  1137.      * use date().
  1138.      * 
  1139.      * @param string|int$format pre-defined format code or string stamp
  1140.      * @throws Gumbo_Exception
  1141.      * @uses Gumbo_Number
  1142.      */
  1143.     public function getDate ($format=null) {
  1144.         try {
  1145.             if (!is_null ($format) && !is_numeric ($format) && !is_string ($format)) {
  1146.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|str|null' => {$format}:" . gettype ($format));
  1147.             }
  1148.             
  1149.             if (is_null ($format)) { $format = 0; }
  1150.             if (is_numeric ($format)) {
  1151.                 $format = (int) $format;
  1152.                 if ($format < 0 || $format > 7) {
  1153.                     throw new Gumbo_Exception ("Out Of Range '0 <= format <= 7'");
  1154.                 }
  1155.             }
  1156.         } catch (Gumbo_Exception $e) {
  1157.             $e->setFunction (__METHOD__);
  1158.             gumbo_trigger ($e);
  1159.             $format = 0;
  1160.         }
  1161.         
  1162.         $txt = false;
  1163.         if (is_numeric ($format)) {
  1164.             if ($format == 0) { return $this->getYear () . "-" . $this->getMonth (1) . "-" . $this->getDay (1); }
  1165.             if ($format == 1) { return $this->getYear () . $this->getMonth (1); }
  1166.             if ($format == 2) { return $this->getYear () . $this->getMonth (1) . $this->getDay (1); }
  1167.             if ($format == 3) { return $this->getMonth (1) . "/" . $this->getDay (1) . "/" . $this->getYear (); }
  1168.             if ($format == 4) { return $this->getMonth () . "/" . $this->getDay () . "/" . $this->getYear (); }
  1169.             if ($format == 5) { return $this->getMonth (2) . " " . $this->getDay () . Gumbo_Number::getSuffix ($this->getDay ()) . ", " . $this->getYear (); }
  1170.             if ($format == 6) { return $this->getMonth (3) . " " . $this->getDay () . Gumbo_Number::getSuffix ($this->getDay ()) . ", " . $this->getYear (); }
  1171.             if ($format == 7) { return $this->getDay (5) . ", " . $this->getDay () . " " . $this->getMonth (2) . " " . $this->getYear (); }
  1172.         } else {
  1173.             $stamp = mktime ($this->getHour (), $this->getMinute (), $this->getSecond (), $this->getMonth (), $this->getDay (), $this->getYear ());
  1174.             if (strstr ($format, "%")) {
  1175.                 return strftime ($format, $stamp);
  1176.             } else {
  1177.                 return date ($format, $stamp);
  1178.             }
  1179.         }
  1180.     }
  1181.     
  1182.     /**
  1183.      * Returns a formatted Time string
  1184.      * Time Format:
  1185.      * - 0 => hh:mm:ss (default)
  1186.      * - 1 => hh
  1187.      * - 2 => hhmm
  1188.      * - 3 => hhmmss
  1189.      * - 4 => hh:mm
  1190.      * - 5 => hh:mm [am|pm]
  1191.      * - 6 => [h]h:mm
  1192.      * - 7 => [h]h:mm [am|pm]
  1193.      * - 8 => hh:mm:ss
  1194.      * - 9 => hh:mm:ss [am|pm]
  1195.      * - 10 => [h]h:mm:ss
  1196.      * - 11 => [h]h:mm:ss [am|pm]
  1197.      * @param int $format pre-defined time format
  1198.      * @return string 
  1199.      * @throws Gumbo_Exception
  1200.      */
  1201.     public function getTime ($format=null) {
  1202.         try {
  1203.             if (!is_null ($format) && !is_numeric ($format)) {
  1204.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1205.             }
  1206.             
  1207.             if (is_null ($format)) { $format = 0; }
  1208.             $format = (int) $format;
  1209.             
  1210.             if ($format < 0 || $format > 11) {
  1211.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 11'");
  1212.             }
  1213.         } catch (Gumbo_Exception $e) {
  1214.             $e->setFunction (__METHOD__);
  1215.             gumbo_trigger ($e);
  1216.             $format = 0;
  1217.         }
  1218.         
  1219.         if (!is_null ($format)) {
  1220.             if ($format == 0) { return $this->getHour (1) . ":" . $this->getMinute (1) . ":" . $this->getSecond (1); }
  1221.             if ($format == 1) { return $this->getHour (1); }
  1222.             if ($format == 2) { return $this->getHour (1) . $this->getMinute (1); }
  1223.             if ($format == 3) { return $this->getHour (1) . $this->getMinute (1) . $this->getSecond (1); }
  1224.             if ($format == 4) { return $this->getHour (1) . ":" . $this->getMinute (1); }
  1225.             if ($format == 5) { return $this->getHour (3) . ":" . $this->getMinute (1) . " " . $this->meridien (); }
  1226.             if ($format == 6) { return $this->getHour () . ":" . $this->getMinute (1); }
  1227.             if ($format == 7) { return $this->getHour (2) . ":" . $this->getMinute (1) . " " . $this->meridien (); }
  1228.             if ($format == 8) { return $this->getHour (1) . ":" . $this->getMinute (1) . ":" . $this->getSecond (1); }
  1229.             if ($format == 9) { return $this->getHour (3) . ":" . $this->getMinute (1) . ":" . $this->getSecond (1) . " " . $this->meridien (); }
  1230.             if ($format == 10) { return $this->getHour () . ":" . $this->getMinute (1) . ":" . $this->getSecond (1); }
  1231.             if ($format == 11) { return $this->getHour (2) . ":" . $this->getMinute (1) . ":" . $this->getSecond (1) . " " . $this->meridien (); }
  1232.         }
  1233.     }
  1234.     
  1235.     /**
  1236.      * Returns the Century
  1237.      * @return int|string
  1238.      * @throws Gumbo_Exception
  1239.      * @uses Gumbo_Number
  1240.      */
  1241.     public function getCentury ($as_string=false) {
  1242.         try {
  1243.             // verify precondition
  1244.             if (!is_bool ($as_string)) {
  1245.                 throw new Gumbo_Exception ("Invalid Argument 'as_string:bool' => {$as_string}:" . gettype ($as_string));
  1246.             }
  1247.         } catch (Gumbo_Exception $e) {
  1248.             $e->setFunction (__METHOD__);
  1249.             gumbo_trigger ($e);
  1250.             $as_string = false;
  1251.         }
  1252.         
  1253.         // return as string
  1254.         if ($as_string) {
  1255.             return Gumbo_Number::getSuffix ($this->getCentury ());
  1256.         }
  1257.         
  1258.         // return as int
  1259.         return floor ($this->getYear () / 100);
  1260.     }
  1261.     
  1262.     /**
  1263.      * Returns the Year requested format
  1264.      * 
  1265.      * Formats:
  1266.      * 0 -> yyyy
  1267.      * 1 -> yy
  1268.      * 
  1269.      * @param int $format 
  1270.      * @return int|string
  1271.      * @throws Gumbo_Exception
  1272.      */
  1273.     public function getYear ($format=null) {
  1274.         try {
  1275.             // verify precondition
  1276.             if (!is_null ($format) && !is_int ($format)) {
  1277.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1278.             }
  1279.             
  1280.             if (is_null ($format)) { $format = 0; }
  1281.             $format = (int) $format;
  1282.             
  1283.             if ($format < 0 || $format > 1) {
  1284.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 1'");
  1285.             }
  1286.         } catch (Gumbo_Exception $e) {
  1287.             $e->setFunction (__METHOD__);
  1288.             gumbo_trigger ($e);
  1289.             $format = 0;
  1290.         }
  1291.         
  1292.         if ($format == 1) { return substr ($this->_year, 2); }
  1293.         return $this->_year;
  1294.     }
  1295.     
  1296.     /**
  1297.      * Returns the Month in the requested format
  1298.      * 
  1299.      * Formats:
  1300.      * 0 -> [m]m
  1301.      * 1 -> mm
  1302.      * 2 -> Mon (abbreviation)
  1303.      * 3 -> Month (full name)
  1304.      * 
  1305.      * @param int $format 
  1306.      * @return int|string
  1307.      * @throws Gumbo_Exception
  1308.      */
  1309.     public function getMonth ($format=null) {
  1310.         try {
  1311.             // verify precondition
  1312.             if (!is_null ($format) && !is_int ($format)) {
  1313.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1314.             }
  1315.             
  1316.             if (is_null ($format)) { $format = 0; }
  1317.             $format = (int) $format;
  1318.             
  1319.             if ($format < 0 || $format > 3) {
  1320.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 3'");
  1321.             }
  1322.         } catch (Gumbo_Exception $e) {
  1323.             $e->setFunction (__METHOD__);
  1324.             gumbo_trigger ($e);
  1325.             $format = 0;
  1326.         }
  1327.         
  1328.         if ($format == 1) { if (strlen ($this->_month) == 1) { return "0" . $this->_month; } else { $format = 0; } }
  1329.         if ($format == 2) { return substr ($this->_facts_month [$this->_month]['name'], 0, 3); }
  1330.         if ($format == 3) { return $this->_facts_month [$this->_month]['name']; }
  1331.         
  1332.         return $this->_month;
  1333.     }
  1334.     
  1335.     /**
  1336.      * Returns the Week
  1337.      * @return int 
  1338.      */
  1339.     public function getWeek () {
  1340.         return $this->_calcWeekOfYear ();
  1341.     }
  1342.     
  1343.     /**
  1344.      * Returns the Day in the requested format
  1345.      * 
  1346.      * Formats:
  1347.      * - 0 => [d]d
  1348.      * - 1 => dd
  1349.      * - 2 => ## (numerical day of week)
  1350.      * - 3 => Day (abbreviation)
  1351.      * - 4 => Day (full name)
  1352.      * - 5 => ## (day of year)
  1353.      * 
  1354.      * @param int $format 
  1355.      * @return int|string
  1356.      * @throws Gumbo_Exception
  1357.      */
  1358.     public function getDay ($format=null) {
  1359.         try {
  1360.             // verify precondition
  1361.             if (!is_null ($format) && !is_int ($format)) {
  1362.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1363.             }
  1364.             
  1365.             if (is_null ($format)) { $format = 0; }
  1366.             $format = (int) $format;
  1367.             
  1368.             if ($format < 0 || $format > 5) {
  1369.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 5'");
  1370.             }
  1371.         } catch (Gumbo_Exception $e) {
  1372.             $e->setFunction (__METHOD__);
  1373.             gumbo_trigger ($e);
  1374.             $format = 0;
  1375.         }
  1376.         
  1377.         if ($format == 1) { if (strlen ($this->_day) == 1) { return "0" . $this->_day; } else { $format = 0; } }
  1378.         if ($format == 2) { return $this->_calcDayOfWeek (); }
  1379.         if ($format == 3) { return substr ($this->_facts_day [$this->_calcDayOfWeek ()], 0, 3); }
  1380.         if ($format == 4) { return $this->_facts_day [$this->_calcDayOfWeek ()]; }
  1381.         if ($format == 5) { return $this->_calcDayOfYear (); }
  1382.         
  1383.         return $this->_day;
  1384.     }
  1385.     
  1386.     /**
  1387.      * Returns the Hour in the requested format
  1388.      * 
  1389.      * Formats:
  1390.      * - 0 => [h]h (24-hour format)
  1391.      * - 1 => hh (24-hour format)
  1392.      * - 2 => [h]h (12-hour format)
  1393.      * - 3 => hh (12-hour format)
  1394.      * 
  1395.      * @param int $format 
  1396.      * @return int|string
  1397.      * @throws Gumbo_Exception
  1398.      */
  1399.     public function getHour ($format=null) {
  1400.         try {
  1401.             // verify precondition
  1402.             if (!is_null ($format) && !is_int ($format)) {
  1403.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1404.             }
  1405.             
  1406.             if (is_null ($format)) { $format = 0; }
  1407.             $format = (int) $format;
  1408.             
  1409.             if ($format < 0 || $format > 3) {
  1410.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 3'");
  1411.             }
  1412.         } catch (Gumbo_Exception $e) {
  1413.             $e->setFunction (__METHOD__);
  1414.             gumbo_trigger ($e);
  1415.             $format = 0;
  1416.         }
  1417.         
  1418.         if ($format == 1) {
  1419.             if (strlen ($this->_hour) == 1) {
  1420.                 return "0" . $this->_hour;
  1421.             } else {
  1422.                 $format = 0;
  1423.             }
  1424.         }
  1425.         
  1426.         $hr = $this->_hour;
  1427.         if ($hr > 12) { $hr -= 12; }
  1428.         if ($hr == 0) { $hr = 12; }
  1429.         
  1430.         if ($format == 2) { return $hr; }
  1431.         if ($format == 3) {
  1432.             if (strlen ($hr) == 1) {
  1433.                 return "0" . $hr;
  1434.             } else {
  1435.                 return $hr;
  1436.             }
  1437.         }
  1438.         
  1439.         return $this->_hour;
  1440.     }
  1441.     
  1442.     /**
  1443.      * Returns the Minutes in the requested format
  1444.      * 
  1445.      * Format:
  1446.      * - 0 => [m]m
  1447.      * - 1 => mm
  1448.      * 
  1449.      * @param int $format 
  1450.      * @return int|string
  1451.      * @throws Gumbo_Exception
  1452.      */
  1453.     public function getMinute ($format=null) {
  1454.         try {
  1455.             // verify precondition
  1456.             if (!is_null ($format) && !is_int ($format)) {
  1457.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1458.             }
  1459.             
  1460.             if (is_null ($format)) { $format = 0; }
  1461.             $format = (int) $format;
  1462.             
  1463.             if ($format < 0 || $format > 1) {
  1464.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 1'");
  1465.             }
  1466.         } catch (Gumbo_Exception $e) {
  1467.             $e->setFunction (__METHOD__);
  1468.             gumbo_trigger ($e);
  1469.             $format = 0;
  1470.         }
  1471.         
  1472.         if ($format == 1) {
  1473.             if (strlen ($this->_minute) == 1) {
  1474.                 return "0" . $this->_minute;
  1475.             } else {
  1476.                 $format = 0;
  1477.             }
  1478.         }
  1479.         
  1480.         return $this->_minute;
  1481.     }
  1482.     
  1483.     /**
  1484.      * Returns the Seconds in the requested format
  1485.      * 
  1486.      * Format:
  1487.      * - 0 => [s]s
  1488.      * - 1 => ss
  1489.      * 
  1490.      * @param int $format 
  1491.      * @return int|string
  1492.      * @throws Gumbo_Exception
  1493.      */
  1494.     public function getSecond ($format=null) {
  1495.         try {
  1496.             // verify precondition
  1497.             if (!is_null ($format) && !is_int ($format)) {
  1498.                 throw new Gumbo_Exception ("Invalid Argument 'format:int|null' => {$format}:" . gettype ($format));
  1499.             }
  1500.             
  1501.             if (is_null ($format)) { $format = 0; }
  1502.             $format = (int) $format;
  1503.             
  1504.             if ($format < 0 || $format > 1) {
  1505.                 throw new Gumbo_Exception ("Out Of Range '0 <= format <= 1'");
  1506.             }
  1507.         } catch (Gumbo_Exception $e) {
  1508.             $e->setFunction (__METHOD__);
  1509.             gumbo_trigger ($e);
  1510.             $format = 0;
  1511.         }
  1512.         
  1513.         if ($format == 1) {
  1514.             if (strlen ($this->_second) == 1) {
  1515.                 return "0" . $this->_second;
  1516.             } else {
  1517.                 $format = 0;
  1518.             }
  1519.         }
  1520.         
  1521.         return $this->_second;
  1522.     }
  1523.     
  1524.     
  1525.     
  1526.     /**
  1527.      * Returns an array of factual months
  1528.      * @return array 
  1529.      */
  1530.     public function getMonthFacts () {
  1531.         return $this->_facts_month;
  1532.     }
  1533.     
  1534.     /**
  1535.      * Returns the total days within a month
  1536.      * @param int $month 
  1537.      * @return int 
  1538.      * @throws Gumbo_Exception
  1539.      */
  1540.     public function totalDays ($month=null) {
  1541.         try {
  1542.             // verify precondition
  1543.             if (!is_numeric ($month)) {
  1544.                 throw new Gumbo_Exception ("Invalid Argument 'month:num' => {$month}:" . gettype ($month));
  1545.             }
  1546.             if ($month <= 0 || $month >= 13) {
  1547.                 throw new Gumbo_Exception ("Out Of Range '0 < month < 13' => {$month}");
  1548.             }
  1549.             $month = (int) $month;
  1550.             
  1551.             return $this->_facts_month [$month]['days'];
  1552.         } catch (Gumbo_Exception $e) {
  1553.             $e->setFunction (__METHOD__);
  1554.             gumbo_trigger ($e);
  1555.         }
  1556.         return null;
  1557.     }
  1558.     
  1559.     
  1560.     
  1561.     /**
  1562.      * Returns if the current day is on the weekend
  1563.      * @return bool 
  1564.      */
  1565.     public function isWeekend () {
  1566.         $val = false;
  1567.         if ($this->getDate (2) == 0 || $this->getDate (2) == 6) {
  1568.             $val = true;
  1569.         }
  1570.         return $val;
  1571.     }
  1572.     
  1573.     /**
  1574.      * Returns if the current day is on the weekday
  1575.      * @return bool 
  1576.      */
  1577.     public function isWeekday () {
  1578.         return !$this->isWeekend ();
  1579.     }
  1580.     
  1581.     /**
  1582.      * Returns if the current day is a holiday
  1583.      * @return bool 
  1584.      */
  1585.     public function isHoliday () {
  1586.         return $this->_holiday;
  1587.     }
  1588.     
  1589.     
  1590.     
  1591.     /**
  1592.      * Returns if a Sunday
  1593.      * @return bool 
  1594.      */
  1595.     public function isSunday () {
  1596.         return ($this->getDay (2) == 0);
  1597.     }
  1598.     
  1599.     /**
  1600.      * Returns if a Monday
  1601.      * @return bool 
  1602.      */
  1603.     public function isMonday () {
  1604.         return ($this->getDay (2) == 1);
  1605.     }
  1606.     
  1607.     /**
  1608.      * Returns if a Tuesday
  1609.      * @return bool 
  1610.      */
  1611.     public function isTuesday () {
  1612.         return ($this->getDay (2) == 2);
  1613.     }
  1614.     
  1615.     /**
  1616.      * Returns if a Wednesday
  1617.      * @return bool 
  1618.      */
  1619.     public function isWednesday () {
  1620.         return ($this->getDay (2) == 3);
  1621.     }
  1622.     
  1623.     /**
  1624.      * Returns if a Thursday
  1625.      * @return bool 
  1626.      */
  1627.     public function isThursday () {
  1628.         return ($this->getDay (2) == 4);
  1629.     }
  1630.     
  1631.     /**
  1632.      * Returns if a Friday
  1633.      * @return bool 
  1634.      */
  1635.     public function isFriday () {
  1636.         return ($this->getDay (2) == 5);
  1637.     }
  1638.     
  1639.     /**
  1640.      * Returns if a Saturday
  1641.      * @return bool 
  1642.      */
  1643.     public function isSaturday () {
  1644.         return ($this->getDay (2) == 6);
  1645.     }
  1646.     
  1647.     
  1648.     
  1649.     /**
  1650.      * Returns if January
  1651.      * @return bool 
  1652.      */
  1653.     public function isJanuary () {
  1654.         return ($this->getMonth () == 1);
  1655.     }
  1656.     
  1657.     /**
  1658.      * Returns if February
  1659.      * @return bool 
  1660.      */
  1661.     public function isFebruary () {
  1662.         return ($this->getMonth () == 2);
  1663.     }
  1664.     
  1665.     /**
  1666.      * Returns if March
  1667.      * @return bool 
  1668.      */
  1669.     public function isMarch () {
  1670.         return ($this->getMonth () == 3);
  1671.     }
  1672.     
  1673.     /**
  1674.      * Returns if April
  1675.      * @return bool 
  1676.      */
  1677.     public function isApril () {
  1678.         return ($this->getMonth () == 4);
  1679.     }
  1680.     
  1681.     /**
  1682.      * Returns if May
  1683.      * @return bool 
  1684.      */
  1685.     public function isMay () {
  1686.         return ($this->getMonth () == 5);
  1687.     }
  1688.     
  1689.     /**
  1690.      * Returns if June
  1691.      * @return bool 
  1692.      */
  1693.     public function isJune () {
  1694.         return ($this->getMonth () == 6);
  1695.     }
  1696.     
  1697.     /**
  1698.      * Returns if July
  1699.      * @return bool 
  1700.      */
  1701.     public function isJuly () {
  1702.         return ($this->getMonth () == 7);
  1703.     }
  1704.     
  1705.     /**
  1706.      * Returns if August
  1707.      * @return bool 
  1708.      */
  1709.     public function isAugust () {
  1710.         return ($this->getMonth () == 8);
  1711.     }
  1712.     
  1713.     /**
  1714.      * Returns if September
  1715.      * @return bool 
  1716.      */
  1717.     public function isSeptember () {
  1718.         return ($this->getMonth () == 9);
  1719.     }
  1720.     
  1721.     /**
  1722.      * Returns if October
  1723.      * @return bool 
  1724.      */
  1725.     public function isOctober () {
  1726.         return ($this->getMonth () == 10);
  1727.     }
  1728.     
  1729.     /**
  1730.      * Returns if November
  1731.      * @return bool 
  1732.      */
  1733.     public function isNovember () {
  1734.         return ($this->getMonth () == 11);
  1735.     }
  1736.     
  1737.     /**
  1738.      * Returns if December
  1739.      * @return bool 
  1740.      */
  1741.     public function isDecember () {
  1742.         return ($this->getMonth () == 12);
  1743.     }
  1744.     
  1745.     
  1746.     
  1747.     /**
  1748.      * Returns if Winter
  1749.      * @return boolean 
  1750.      */
  1751.     public function isWinter () {
  1752.         return ($this->isDecember () || $this->isJanuary () || $this->isFebruary ());
  1753.     }
  1754.     
  1755.     /**
  1756.      * Returns if Spring
  1757.      * @return boolean 
  1758.      */
  1759.     public function isSpring () {
  1760.         return ($this->isMarch () || $this->isApril () || $this->isMay ());
  1761.     }
  1762.     
  1763.     /**
  1764.      * Returns if Summer
  1765.      * @return boolean 
  1766.      */
  1767.     public function isSummer () {
  1768.         return ($this->isJune () || $this->isJuly () || $this->isAugust ());
  1769.     }
  1770.     
  1771.     /**
  1772.      * Returns if Fall
  1773.      * @return boolean 
  1774.      */
  1775.     public function isFall () {
  1776.         return ($this->isSeptember () || $this->isOctober () || $this->isNovember ());
  1777.     }
  1778.     
  1779.     
  1780.     
  1781.     /**
  1782.      * Returns the difference from the supplied Date
  1783.      * @param Gumbo_Interface_Date $date 
  1784.      * @return array [when|year|month|day|hour|minute|second]
  1785.      */
  1786.     public function diff (Gumbo_Interface_Date $date) {
  1787.         $diff = array ("when"=>"equal", "year"=>0, "month"=>0, "day"=>0, "hour"=>0, "minute"=>0, "second"=>0);
  1788.         
  1789.         $obj = clone $date;
  1790.         if ($this->get (5) > $obj->get (5)) { $diff ['when'] = "before"; }
  1791.         if ($this->get (5) < $obj->get (5)) { $diff ['when'] = "after"; }
  1792.         
  1793.         // check year
  1794.         $num = 0;
  1795.         $func = "nextYear";
  1796.         if ($obj->get (5) > $this->get (5)) { $func = "prevYear"; }
  1797.         while ($obj->getYear () != $this->getYear ()) {
  1798.             $obj->$func ();
  1799.             $num++;
  1800.         }
  1801.         $diff ['year'] = $num;
  1802.         
  1803.         // check month
  1804.         $num = 0;
  1805.         $func = "nextMonth";
  1806.         if ($obj->get (5) > $this->get (5)) { $func = "prevMonth"; }
  1807.         while ($obj->getMonth () != $this->getMonth ()) {
  1808.             $obj->$func ();
  1809.             $num++;
  1810.         }
  1811.         $diff ['month'] = $num;
  1812.         
  1813.         // check day
  1814.         $num = 0;
  1815.         $func = "nextDay";
  1816.         if ($obj->get (5) > $this->get (5)) { $func = "prevDay"; }
  1817.         while ($obj->getDay () != $this->getDay ()) {
  1818.             $obj->$func ();
  1819.             $num++;
  1820.         }
  1821.         $diff ['day'] = $num;
  1822.         
  1823.         // check hour
  1824.         $num = 0;
  1825.         $func = "nextHour";
  1826.         if ($obj->get (5) > $this->get (5)) { $func = "prevHour"; }
  1827.         while ($obj->getHour () != $this->getHour ()) {
  1828.             $obj->$func ();
  1829.             $num++;
  1830.         }
  1831.         $diff ['hour'] = $num;
  1832.         
  1833.         // check minutes
  1834.         $num = 0;
  1835.         $func = "nextMinute";
  1836.         if ($obj->get (5) > $this->get (5)) { $func = "prevMinute"; }
  1837.         while ($obj->getMinute () != $this->getMinute ()) {
  1838.             $obj->$func ();
  1839.             $num++;
  1840.         }
  1841.         $diff ['minute'] = $num;
  1842.         
  1843.         // check seconds
  1844.         $num = 0;
  1845.         $func = "nextSecond";
  1846.         if ($obj->get (5) > $this->get (5)) { $func = "prevSecond"; }
  1847.         while ($obj->getSecond () != $this->getSecond ()) {
  1848.             $obj->$func ();
  1849.             $num++;
  1850.         }
  1851.         $diff ['second'] = $num;
  1852.         
  1853.         return $diff;
  1854.     }
  1855.     
  1856.     /**
  1857.      * Returns the number of Years difference
  1858.      * @param int|Gumbo_Interface_Date$val 
  1859.      * @return int 
  1860.      */
  1861.     public function diffYear ($val) {
  1862.         if ($val instanceof Gumbo_Interface_Date) {
  1863.             $val = $val->getYear ();
  1864.         }
  1865.         if (!is_numeric ($val)) { return 0; }
  1866.         $val = (int) $val;
  1867.         
  1868.         $num = 0;
  1869.         if ($val > $this->getYear ()) {
  1870.             while ($val > $this->getYear ()) {
  1871.                 $val--;
  1872.                 $num++;
  1873.             }
  1874.         } else {
  1875.             while ($val < $this->getYear ()) {
  1876.                 $val++;
  1877.                 $num--;
  1878.             }
  1879.         }
  1880.         
  1881.         return $num;
  1882.     }
  1883.     
  1884.     /**
  1885.      * Returns the number of Months difference
  1886.      * @param Gumbo_Interface_Date $val 
  1887.      * @return int 
  1888.      */
  1889.     public function diffMonth (Gumbo_Interface_Date $val) {
  1890.         $obj = clone $val;
  1891.         
  1892.         $num = 0;
  1893.         if ($this->getDate (1) > $obj->getDate (1)) {
  1894.             while ($this->getDate (1) > $obj->getDate (1)) {
  1895.                 $obj->nextMonth ();
  1896.                 $num--;
  1897.             }
  1898.         } else {
  1899.             while ($this->getDate (1) < $obj->getDate (1)) {
  1900.                 $obj->prevMonth ();
  1901.                 $num++;
  1902.             }
  1903.         }
  1904.         
  1905.         unset ($obj);
  1906.         return $num;
  1907.     }
  1908.     
  1909.     /**
  1910.      * Returns the number of Weeks difference
  1911.      * @param Gumbo_Interface_Date $val 
  1912.      * @return int 
  1913.      */
  1914.     public function diffWeek (Gumbo_Interface_Date $val) {
  1915.         $obj = clone $val;
  1916.         
  1917.         $num = 0;
  1918.         if ($this->getDate (2) > $obj->getDate (2)) {
  1919.             while ($this->getDate (2) > $obj->getDate (2)) {
  1920.                 $obj->nextWeek ();
  1921.                 $num--;
  1922.             }
  1923.         } else {
  1924.             while ($this->getDate (2) < $obj->getDate (2)) {
  1925.                 $obj->prevWeek ();
  1926.                 $num++;
  1927.             }
  1928.         }
  1929.         
  1930.         unset ($obj);
  1931.         return $num;
  1932.     }
  1933.     
  1934.     /**
  1935.      * Returns the number of Days difference
  1936.      * @param Gumbo_Interface_Date $val 
  1937.      * @return int 
  1938.      */
  1939.     public function diffDay (Gumbo_Interface_Date $val) {
  1940.         $obj = clone $val;
  1941.         
  1942.         $num = 0;
  1943.         if ($this->getDate (2) > $obj->getDate (2)) {
  1944.             while ($this->getDate (2) > $obj->getDate (2)) {
  1945.                 $obj->nextDay ();
  1946.                 $num--;
  1947.             }
  1948.         } else {
  1949.             while ($this->getDate (2) < $obj->getDate (2)) {
  1950.                 $obj->prevDay ();
  1951.                 $num++;
  1952.             }
  1953.         }
  1954.         
  1955.         unset ($obj);
  1956.         return $num;
  1957.     }
  1958.     
  1959.     
  1960.     
  1961.     /**
  1962.      * Returns the AM/PM time value
  1963.      * @param bool $in_caps returns value in caps
  1964.      * @return string 
  1965.      * @throws Gumbo_Exception
  1966.      */
  1967.     public function meridien ($in_caps=false) {
  1968.         try {
  1969.             // verify precondition
  1970.             if (!is_bool ($in_caps)) {
  1971.                 throw new Gumbo_Exception ("Invalid Argument 'in_caps:bool' => {$in_caps}:" . gettype ($in_caps));
  1972.             }
  1973.         } catch (Gumbo_Exception $e) {
  1974.             $e->setFunction (__METHOD__);
  1975.             gumbo_trigger ($e);
  1976.             $in_caps = false;
  1977.         }
  1978.         
  1979.         $tmp = "am";
  1980.         if ($this->getHour () > 11) { $tmp = "pm"; }
  1981.         
  1982.         if ($in_caps) {
  1983.             return strtoupper ($tmp);
  1984.         }
  1985.         return $tmp;
  1986.     }
  1987.     
  1988. }
  1989.  
  1990. ?>