home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Date / Calc.php next >
Encoding:
PHP Script  |  2008-07-02  |  68.5 KB  |  2,117 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  3.  
  4. // {{{ Header
  5.  
  6. /**
  7.  * Calculates, manipulates and retrieves dates
  8.  *
  9.  * It does not rely on 32-bit system time stamps, so it works dates
  10.  * before 1970 and after 2038.
  11.  *
  12.  * PHP versions 4 and 5
  13.  *
  14.  * LICENSE:
  15.  *
  16.  * Copyright (c) 1999-2006 Monte Ohrt, Pierre-Alain Joye, Daniel Convissor
  17.  * All rights reserved.
  18.  *
  19.  * Redistribution and use in source and binary forms, with or without
  20.  * modification, are permitted under the terms of the BSD License.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  23.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  24.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  25.  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  26.  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  27.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  28.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  30.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  31.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  32.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33.  * POSSIBILITY OF SUCH DAMAGE.
  34.  *
  35.  * @category   Date and Time
  36.  * @package    Date
  37.  * @author     Monte Ohrt <monte@ispi.net>
  38.  * @author     Pierre-Alain Joye <pajoye@php.net>
  39.  * @author     Daniel Convissor <danielc@php.net>
  40.  * @copyright  1999-2006 Monte Ohrt, Pierre-Alain Joye, Daniel Convissor
  41.  * @license    http://www.opensource.org/licenses/bsd-license.php
  42.  *             BSD License
  43.  * @version    CVS: $Id: Calc.php,v 1.35 2006/11/21 23:01:13 firman Exp $
  44.  * @link       http://pear.php.net/package/Date
  45.  * @since      File available since Release 1.2
  46.  */
  47.  
  48. // }}}
  49.  
  50. if (!defined('DATE_CALC_BEGIN_WEEKDAY')) {
  51.     /**
  52.      * Defines what day starts the week
  53.      *
  54.      * Monday (1) is the international standard.
  55.      * Redefine this to 0 if you want weeks to begin on Sunday.
  56.      */
  57.     define('DATE_CALC_BEGIN_WEEKDAY', 1);
  58. }
  59.  
  60. if (!defined('DATE_CALC_FORMAT')) {
  61.     /**
  62.      * The default value for each method's $format parameter
  63.      *
  64.      * The default is '%Y%m%d'.  To override this default, define
  65.      * this constant before including Calc.php.
  66.      *
  67.      * @since Constant available since Release 1.4.4
  68.      */
  69.     define('DATE_CALC_FORMAT', '%Y%m%d');
  70. }
  71.  
  72. // {{{ Class: Date_Calc
  73.  
  74. /**
  75.  * Calculates, manipulates and retrieves dates
  76.  *
  77.  * It does not rely on 32-bit system time stamps, so it works dates
  78.  * before 1970 and after 2038.
  79.  *
  80.  * @author     Monte Ohrt <monte@ispi.net>
  81.  * @author     Daniel Convissor <danielc@php.net>
  82.  * @copyright  1999-2006 Monte Ohrt, Pierre-Alain Joye, Daniel Convissor
  83.  * @license    http://www.opensource.org/licenses/bsd-license.php
  84.  *             BSD License
  85.  * @version    Release: 1.4.7
  86.  * @link       http://pear.php.net/package/Date
  87.  * @since      Class available since Release 1.2
  88.  */
  89. class Date_Calc
  90. {
  91.     // {{{ dateFormat()
  92.  
  93.     /**
  94.      * Formats the date in the given format, much like strfmt()
  95.      *
  96.      * This function is used to alleviate the problem with 32-bit numbers for
  97.      * dates pre 1970 or post 2038, as strfmt() has on most systems.
  98.      * Most of the formatting options are compatible.
  99.      *
  100.      * Formatting options:
  101.      * <pre>
  102.      * %a   abbreviated weekday name (Sun, Mon, Tue)
  103.      * %A   full weekday name (Sunday, Monday, Tuesday)
  104.      * %b   abbreviated month name (Jan, Feb, Mar)
  105.      * %B   full month name (January, February, March)
  106.      * %d   day of month (range 00 to 31)
  107.      * %e   day of month, single digit (range 0 to 31)
  108.      * %E   number of days since unspecified epoch (integer)
  109.      *        (%E is useful for passing a date in a URL as
  110.      *        an integer value. Then simply use
  111.      *        daysToDate() to convert back to a date.)
  112.      * %j   day of year (range 001 to 366)
  113.      * %m   month as decimal number (range 1 to 12)
  114.      * %n   newline character (\n)
  115.      * %t   tab character (\t)
  116.      * %w   weekday as decimal (0 = Sunday)
  117.      * %U   week number of current year, first sunday as first week
  118.      * %y   year as decimal (range 00 to 99)
  119.      * %Y   year as decimal including century (range 0000 to 9999)
  120.      * %%   literal '%'
  121.      * </pre>
  122.      *
  123.      * @param int    $day     the day of the month
  124.      * @param int    $month   the month
  125.      * @param int    $year    the year.  Use the complete year instead of the
  126.      *                         abbreviated version.  E.g. use 2005, not 05.
  127.      *                         Do not add leading 0's for years prior to 1000.
  128.      * @param string $format  the format string
  129.      *
  130.      * @return string  the date in the desired format
  131.      *
  132.      * @access public
  133.      * @static
  134.      */
  135.     function dateFormat($day, $month, $year, $format)
  136.     {
  137.         if (!Date_Calc::isValidDate($day, $month, $year)) {
  138.             $year  = Date_Calc::dateNow('%Y');
  139.             $month = Date_Calc::dateNow('%m');
  140.             $day   = Date_Calc::dateNow('%d');
  141.         }
  142.  
  143.         $output = '';
  144.  
  145.         for ($strpos = 0; $strpos < strlen($format); $strpos++) {
  146.             $char = substr($format, $strpos, 1);
  147.             if ($char == '%') {
  148.                 $nextchar = substr($format, $strpos + 1, 1);
  149.                 switch($nextchar) {
  150.                     case 'a':
  151.                         $output .= Date_Calc::getWeekdayAbbrname($day, $month, $year);
  152.                         break;
  153.                     case 'A':
  154.                         $output .= Date_Calc::getWeekdayFullname($day, $month, $year);
  155.                         break;
  156.                     case 'b':
  157.                         $output .= Date_Calc::getMonthAbbrname($month);
  158.                         break;
  159.                     case 'B':
  160.                         $output .= Date_Calc::getMonthFullname($month);
  161.                         break;
  162.                     case 'd':
  163.                         $output .= sprintf('%02d', $day);
  164.                         break;
  165.                     case 'e':
  166.                         $output .= $day;
  167.                         break;
  168.                     case 'E':
  169.                         $output .= Date_Calc::dateToDays($day, $month, $year);
  170.                         break;
  171.                     case 'j':
  172.                         $output .= Date_Calc::julianDate($day, $month, $year);
  173.                         break;
  174.                     case 'm':
  175.                         $output .= sprintf('%02d', $month);
  176.                         break;
  177.                     case 'n':
  178.                         $output .= "\n";
  179.                         break;
  180.                     case 't':
  181.                         $output .= "\t";
  182.                         break;
  183.                     case 'w':
  184.                         $output .= Date_Calc::dayOfWeek($day, $month, $year);
  185.                         break;
  186.                     case 'U':
  187.                         $output .= Date_Calc::weekOfYear($day, $month, $year);
  188.                         break;
  189.                     case 'y':
  190.                         $output .= substr($year, 2, 2);
  191.                         break;
  192.                     case 'Y':
  193.                         $output .= $year;
  194.                         break;
  195.                     case '%':
  196.                         $output .= '%';
  197.                         break;
  198.                     default:
  199.                         $output .= $char.$nextchar;
  200.                 }
  201.                 $strpos++;
  202.             } else {
  203.                 $output .= $char;
  204.             }
  205.         }
  206.         return $output;
  207.     }
  208.  
  209.     // }}}
  210.     // {{{ defaultCentury()
  211.  
  212.     /**
  213.      * Turns a two digit year into a four digit year
  214.      *
  215.      * From '51 to '99 is in the 1900's, otherwise it's in the 2000's.
  216.      *
  217.      * @param int    $year    the 2 digit year
  218.      *
  219.      * @return string  the 4 digit year
  220.      *
  221.      * @access public
  222.      * @static
  223.      */
  224.     function defaultCentury($year)
  225.     {
  226.         if (strlen($year) == 1) {
  227.             $year = '0' . $year;
  228.         }
  229.         if ($year > 50) {
  230.             return '19' . $year;
  231.         } else {
  232.             return '20' . $year;
  233.         }
  234.     }
  235.  
  236.     // }}}
  237.     // {{{ dateToDays()
  238.  
  239.     /**
  240.      * Converts a date to number of days since a distant unspecified epoch
  241.      *
  242.      * @param int    $day     the day of the month
  243.      * @param int    $month   the month
  244.      * @param int    $year    the year.  Use the complete year instead of the
  245.      *                         abbreviated version.  E.g. use 2005, not 05.
  246.      *                         Do not add leading 0's for years prior to 1000.
  247.      *
  248.      * @return integer  the number of days since the Date_Calc epoch
  249.      *
  250.      * @access public
  251.      * @static
  252.      */
  253.     function dateToDays($day, $month, $year)
  254.     {
  255.         $century = (int)substr($year, 0, 2);
  256.         $year = (int)substr($year, 2, 2);
  257.         if ($month > 2) {
  258.             $month -= 3;
  259.         } else {
  260.             $month += 9;
  261.             if ($year) {
  262.                 $year--;
  263.             } else {
  264.                 $year = 99;
  265.                 $century --;
  266.             }
  267.         }
  268.  
  269.         return (floor((146097 * $century) / 4 ) +
  270.                 floor((1461 * $year) / 4 ) +
  271.                 floor((153 * $month + 2) / 5 ) +
  272.                 $day + 1721119);
  273.     }
  274.  
  275.     // }}}
  276.     // {{{ daysToDate()
  277.  
  278.     /**
  279.      * Converts number of days to a distant unspecified epoch
  280.      *
  281.      * @param int    $days    the number of days since the Date_Calc epoch
  282.      * @param string $format  the string indicating how to format the output
  283.      *
  284.      * @return string  the date in the desired format
  285.      *
  286.      * @access public
  287.      * @static
  288.      */
  289.     function daysToDate($days, $format = DATE_CALC_FORMAT)
  290.     {
  291.         $days   -= 1721119;
  292.         $century = floor((4 * $days - 1) / 146097);
  293.         $days    = floor(4 * $days - 1 - 146097 * $century);
  294.         $day     = floor($days / 4);
  295.  
  296.         $year    = floor((4 * $day +  3) / 1461);
  297.         $day     = floor(4 * $day +  3 - 1461 * $year);
  298.         $day     = floor(($day +  4) / 4);
  299.  
  300.         $month   = floor((5 * $day - 3) / 153);
  301.         $day     = floor(5 * $day - 3 - 153 * $month);
  302.         $day     = floor(($day +  5) /  5);
  303.  
  304.         if ($month < 10) {
  305.             $month +=3;
  306.         } else {
  307.             $month -=9;
  308.             if ($year++ == 99) {
  309.                 $year = 0;
  310.                 $century++;
  311.             }
  312.         }
  313.  
  314.         $century = sprintf('%02d', $century);
  315.         $year    = sprintf('%02d', $year);
  316.         return Date_Calc::dateFormat($day, $month, $century . $year, $format);
  317.     }
  318.  
  319.     // }}}
  320.     // {{{ gregorianToISO()
  321.  
  322.     /**
  323.      * Converts from Gregorian Year-Month-Day to ISO Year-WeekNumber-WeekDay
  324.      *
  325.      * Uses ISO 8601 definitions.  Algorithm by Rick McCarty, 1999 at
  326.      * http://personal.ecu.edu/mccartyr/ISOwdALG.txt .
  327.      * Transcribed to PHP by Jesus M. Castagnetto.
  328.      *
  329.      * @param int    $day     the day of the month
  330.      * @param int    $month   the month
  331.      * @param int    $year    the year.  Use the complete year instead of the
  332.      *                         abbreviated version.  E.g. use 2005, not 05.
  333.      *                         Do not add leading 0's for years prior to 1000.
  334.      *
  335.      * @return string  the date in ISO Year-WeekNumber-WeekDay format
  336.      *
  337.      * @access public
  338.      * @static
  339.      */
  340.     function gregorianToISO($day, $month, $year)
  341.     {
  342.         $mnth = array (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
  343.         $y_isleap = Date_Calc::isLeapYear($year);
  344.         $y_1_isleap = Date_Calc::isLeapYear($year - 1);
  345.         $day_of_year_number = $day + $mnth[$month - 1];
  346.         if ($y_isleap && $month > 2) {
  347.             $day_of_year_number++;
  348.         }
  349.         // find Jan 1 weekday (monday = 1, sunday = 7)
  350.         $yy = ($year - 1) % 100;
  351.         $c = ($year - 1) - $yy;
  352.         $g = $yy + intval($yy / 4);
  353.         $jan1_weekday = 1 + intval((((($c / 100) % 4) * 5) + $g) % 7);
  354.         // weekday for year-month-day
  355.         $h = $day_of_year_number + ($jan1_weekday - 1);
  356.         $weekday = 1 + intval(($h - 1) % 7);
  357.         // find if Y M D falls in YearNumber Y-1, WeekNumber 52 or
  358.         if ($day_of_year_number <= (8 - $jan1_weekday) && $jan1_weekday > 4){
  359.             $yearnumber = $year - 1;
  360.             if ($jan1_weekday == 5 || ($jan1_weekday == 6 && $y_1_isleap)) {
  361.                 $weeknumber = 53;
  362.             } else {
  363.                 $weeknumber = 52;
  364.             }
  365.         } else {
  366.             $yearnumber = $year;
  367.         }
  368.         // find if Y M D falls in YearNumber Y+1, WeekNumber 1
  369.         if ($yearnumber == $year) {
  370.             if ($y_isleap) {
  371.                 $i = 366;
  372.             } else {
  373.                 $i = 365;
  374.             }
  375.             if (($i - $day_of_year_number) < (4 - $weekday)) {
  376.                 $yearnumber++;
  377.                 $weeknumber = 1;
  378.             }
  379.         }
  380.         // find if Y M D falls in YearNumber Y, WeekNumber 1 through 53
  381.         if ($yearnumber == $year) {
  382.             $j = $day_of_year_number + (7 - $weekday) + ($jan1_weekday - 1);
  383.             $weeknumber = intval($j / 7);
  384.             if ($jan1_weekday > 4) {
  385.                 $weeknumber--;
  386.             }
  387.         }
  388.         // put it all together
  389.         if ($weeknumber < 10) {
  390.             $weeknumber = '0'.$weeknumber;
  391.         }
  392.         return $yearnumber . '-' . $weeknumber . '-' . $weekday;
  393.     }
  394.  
  395.     // }}}
  396.     // {{{ dateSeason()
  397.  
  398.     /**
  399.      * Determines julian date of the given season
  400.      *
  401.      * Adapted from previous work in Java by James Mark Hamilton.
  402.      *
  403.      * @param string $season  the season to get the date for: VERNALEQUINOX,
  404.      *                         SUMMERSOLSTICE, AUTUMNALEQUINOX,
  405.      *                         or WINTERSOLSTICE
  406.      * @param string $year    the year in four digit format.  Must be between
  407.      *                         -1000BC and 3000AD.
  408.      *
  409.      * @return float  the julian date the season starts on
  410.      *
  411.      * @author James Mark Hamilton <mhamilton@qwest.net>
  412.      * @author Robert Butler <rob@maxwellcreek.org>
  413.      * @access public
  414.      * @static
  415.      */
  416.     function dateSeason($season, $year = 0)
  417.     {
  418.         if ($year == '') {
  419.             $year = Date_Calc::dateNow('%Y');
  420.         }
  421.         if (($year >= -1000) && ($year <= 1000)) {
  422.             $y = $year / 1000.0;
  423.             switch ($season) {
  424.                 case 'VERNALEQUINOX':
  425.                     $juliandate = (((((((-0.00071 * $y) - 0.00111) * $y) + 0.06134) * $y) + 365242.1374) * $y) + 1721139.29189;
  426.                     break;
  427.                 case 'SUMMERSOLSTICE':
  428.                     $juliandate = (((((((0.00025 * $y) + 0.00907) * $y) - 0.05323) * $y) + 365241.72562) * $y) + 1721233.25401;
  429.                     break;
  430.                 case 'AUTUMNALEQUINOX':
  431.                     $juliandate = (((((((0.00074 * $y) - 0.00297) * $y) - 0.11677) * $y) + 365242.49558) * $y) + 1721325.70455;
  432.                     break;
  433.                 case 'WINTERSOLSTICE':
  434.                 default:
  435.                     $juliandate = (((((((-0.00006 * $y) - 0.00933) * $y) - 0.00769) * $y) + 365242.88257) * $y) + 1721414.39987;
  436.             }
  437.         } elseif (($year > 1000) && ($year <= 3000)) {
  438.             $y = ($year - 2000) / 1000;
  439.             switch ($season) {
  440.                 case 'VERNALEQUINOX':
  441.                     $juliandate = (((((((-0.00057 * $y) - 0.00411) * $y) + 0.05169) * $y) + 365242.37404) * $y) + 2451623.80984;
  442.                     break;
  443.                 case 'SUMMERSOLSTICE':
  444.                     $juliandate = (((((((-0.0003 * $y) + 0.00888) * $y) + 0.00325) * $y) + 365241.62603) * $y) + 2451716.56767;
  445.                     break;
  446.                 case 'AUTUMNALEQUINOX':
  447.                     $juliandate = (((((((0.00078 * $y) + 0.00337) * $y) - 0.11575) * $y) + 365242.01767) * $y) + 2451810.21715;
  448.                     break;
  449.                 case 'WINTERSOLSTICE':
  450.                 default:
  451.                     $juliandate = (((((((0.00032 * $y) - 0.00823) * $y) - 0.06223) * $y) + 365242.74049) * $y) + 2451900.05952;
  452.             }
  453.         }
  454.         return $juliandate;
  455.     }
  456.  
  457.     // }}}
  458.     // {{{ dateNow()
  459.  
  460.     /**
  461.      * Returns the current local date
  462.      *
  463.      * NOTE: This function retrieves the local date using strftime(),
  464.      * which may or may not be 32-bit safe on your system.
  465.      *
  466.      * @param string $format  the string indicating how to format the output
  467.      *
  468.      * @return string  the current date in the specified format
  469.      *
  470.      * @access public
  471.      * @static
  472.      */
  473.     function dateNow($format = DATE_CALC_FORMAT)
  474.     {
  475.         return strftime($format, time());
  476.     }
  477.  
  478.     // }}}
  479.     // {{{ getYear()
  480.  
  481.     /**
  482.      * Returns the current local year in format CCYY
  483.      *
  484.      * @return string  the current year in four digit format
  485.      *
  486.      * @access public
  487.      * @static
  488.      */
  489.     function getYear()
  490.     {
  491.         return Date_Calc::dateNow('%Y');
  492.     }
  493.  
  494.     // }}}
  495.     // {{{ getMonth()
  496.  
  497.     /**
  498.      * Returns the current local month in format MM
  499.      *
  500.      * @return string  the current month in two digit format
  501.      *
  502.      * @access public
  503.      * @static
  504.      */
  505.     function getMonth()
  506.     {
  507.         return Date_Calc::dateNow('%m');
  508.     }
  509.  
  510.     // }}}
  511.     // {{{ getDay()
  512.  
  513.     /**
  514.      * Returns the current local day in format DD
  515.      *
  516.      * @return string  the current day of the month in two digit format
  517.      *
  518.      * @access public
  519.      * @static
  520.      */
  521.     function getDay()
  522.     {
  523.         return Date_Calc::dateNow('%d');
  524.     }
  525.  
  526.     // }}}
  527.     // {{{ julianDate()
  528.  
  529.     /**
  530.      * Returns number of days since 31 December of year before given date
  531.      *
  532.      * @param int    $day     the day of the month, default is current local day
  533.      * @param int    $month   the month, default is current local month
  534.      * @param int    $year    the year in four digit format, default is current local year
  535.      *
  536.      * @return int  the julian date for the date
  537.      *
  538.      * @access public
  539.      * @static
  540.      */
  541.     function julianDate($day = 0, $month = 0, $year = 0)
  542.     {
  543.         if (empty($year)) {
  544.             $year = Date_Calc::dateNow('%Y');
  545.         }
  546.         if (empty($month)) {
  547.             $month = Date_Calc::dateNow('%m');
  548.         }
  549.         if (empty($day)) {
  550.             $day = Date_Calc::dateNow('%d');
  551.         }
  552.         $days = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
  553.         $julian = ($days[$month - 1] + $day);
  554.         if ($month > 2 && Date_Calc::isLeapYear($year)) {
  555.             $julian++;
  556.         }
  557.         return $julian;
  558.     }
  559.  
  560.     // }}}
  561.     // {{{ getWeekdayFullname()
  562.  
  563.     /**
  564.      * Returns the full weekday name for the given date
  565.      *
  566.      * @param int    $day     the day of the month, default is current local day
  567.      * @param int    $month   the month, default is current local month
  568.      * @param int    $year    the year in four digit format, default is current local year
  569.      *
  570.      * @return string  the full name of the day of the week
  571.      *
  572.      * @access public
  573.      * @static
  574.      */
  575.     function getWeekdayFullname($day = 0, $month = 0, $year = 0)
  576.     {
  577.         if (empty($year)) {
  578.             $year = Date_Calc::dateNow('%Y');
  579.         }
  580.         if (empty($month)) {
  581.             $month = Date_Calc::dateNow('%m');
  582.         }
  583.         if (empty($day)) {
  584.             $day = Date_Calc::dateNow('%d');
  585.         }
  586.         $weekday_names = Date_Calc::getWeekDays();
  587.         $weekday = Date_Calc::dayOfWeek($day, $month, $year);
  588.         return $weekday_names[$weekday];
  589.     }
  590.  
  591.     // }}}
  592.     // {{{ getWeekdayAbbrname()
  593.  
  594.     /**
  595.      * Returns the abbreviated weekday name for the given date
  596.      *
  597.      * @param int    $day     the day of the month, default is current local day
  598.      * @param int    $month   the month, default is current local month
  599.      * @param int    $year    the year in four digit format, default is current local year
  600.      * @param int    $length  the length of abbreviation
  601.      *
  602.      * @return string  the abbreviated name of the day of the week
  603.      *
  604.      * @access public
  605.      * @static
  606.      * @see Date_Calc::getWeekdayFullname()
  607.      */
  608.     function getWeekdayAbbrname($day = 0, $month = 0, $year = 0, $length = 3)
  609.     {
  610.         if (empty($year)) {
  611.             $year = Date_Calc::dateNow('%Y');
  612.         }
  613.         if (empty($month)) {
  614.             $month = Date_Calc::dateNow('%m');
  615.         }
  616.         if (empty($day)) {
  617.             $day = Date_Calc::dateNow('%d');
  618.         }
  619.         return substr(Date_Calc::getWeekdayFullname($day, $month, $year),
  620.                       0, $length);
  621.     }
  622.  
  623.     // }}}
  624.     // {{{ getMonthFullname()
  625.  
  626.     /**
  627.      * Returns the full month name for the given month
  628.      *
  629.      * @param int    $month   the month
  630.      *
  631.      * @return string  the full name of the month
  632.      *
  633.      * @access public
  634.      * @static
  635.      */
  636.     function getMonthFullname($month)
  637.     {
  638.         $month = (int)$month;
  639.         if (empty($month)) {
  640.             $month = (int)Date_Calc::dateNow('%m');
  641.         }
  642.         $month_names = Date_Calc::getMonthNames();
  643.         return $month_names[$month];
  644.     }
  645.  
  646.     // }}}
  647.     // {{{ getMonthAbbrname()
  648.  
  649.     /**
  650.      * Returns the abbreviated month name for the given month
  651.      *
  652.      * @param int    $month   the month
  653.      * @param int    $length  the length of abbreviation
  654.      *
  655.      * @return string  the abbreviated name of the month
  656.      *
  657.      * @access public
  658.      * @static
  659.      * @see Date_Calc::getMonthFullname
  660.      */
  661.     function getMonthAbbrname($month, $length = 3)
  662.     {
  663.         $month = (int)$month;
  664.         if (empty($month)) {
  665.             $month = Date_Calc::dateNow('%m');
  666.         }
  667.         return substr(Date_Calc::getMonthFullname($month), 0, $length);
  668.     }
  669.  
  670.     // }}}
  671.     // {{{ getMonthFromFullname()
  672.  
  673.     /**
  674.      * Returns the numeric month from the month name or an abreviation
  675.      *
  676.      * Both August and Aug would return 8.
  677.      *
  678.      * @param string $month  the name of the month to examine.
  679.      *                        Case insensitive.
  680.      *
  681.      * @return integer  the month's number
  682.      *
  683.      * @access public
  684.      * @static
  685.      */
  686.     function getMonthFromFullName($month)
  687.     {
  688.         $month = strtolower($month);
  689.         $months = Date_Calc::getMonthNames();
  690.         while(list($id, $name) = each($months)) {
  691.             if (ereg($month, strtolower($name))) {
  692.                 return $id;
  693.             }
  694.         }
  695.         return 0;
  696.     }
  697.  
  698.     // }}}
  699.     // {{{ getMonthNames()
  700.  
  701.     /**
  702.      * Returns an array of month names
  703.      *
  704.      * Used to take advantage of the setlocale function to return
  705.      * language specific month names.
  706.      *
  707.      * TODO: cache values to some global array to avoid preformace
  708.      * hits when called more than once.
  709.      *
  710.      * @returns array  an array of month names
  711.      *
  712.      * @access public
  713.      * @static
  714.      */
  715.     function getMonthNames()
  716.     {
  717.         $months = array();
  718.         for ($i = 1; $i < 13; $i++) {
  719.             $months[$i] = strftime('%B', mktime(0, 0, 0, $i, 1, 2001));
  720.         }
  721.         return $months;
  722.     }
  723.  
  724.     // }}}
  725.     // {{{ getWeekDays()
  726.  
  727.     /**
  728.      * Returns an array of week days
  729.      *
  730.      * Used to take advantage of the setlocale function to
  731.      * return language specific week days.
  732.      *
  733.      * TODO: cache values to some global array to avoid preformace
  734.      * hits when called more than once.
  735.      *
  736.      * @returns array  an array of week day names
  737.      *
  738.      * @access public
  739.      * @static
  740.      */
  741.     function getWeekDays()
  742.     {
  743.         $weekdays = array();
  744.         for ($i = 0; $i < 7; $i++) {
  745.             $weekdays[$i] = strftime('%A', mktime(0, 0, 0, 1, $i, 2001));
  746.         }
  747.         return $weekdays;
  748.     }
  749.  
  750.     // }}}
  751.     // {{{ dayOfWeek()
  752.  
  753.     /**
  754.      * Returns day of week for given date (0 = Sunday)
  755.      *
  756.      * @param int    $day     the day of the month, default is current local day
  757.      * @param int    $month   the month, default is current local month
  758.      * @param int    $year    the year in four digit format, default is current local year
  759.      *
  760.      * @return int  the number of the day in the week
  761.      *
  762.      * @access public
  763.      * @static
  764.      */
  765.     function dayOfWeek($day = 0, $month = 0, $year = 0)
  766.     {
  767.         if (empty($year)) {
  768.             $year = Date_Calc::dateNow('%Y');
  769.         }
  770.         if (empty($month)) {
  771.             $month = Date_Calc::dateNow('%m');
  772.         }
  773.         if (empty($day)) {
  774.             $day = Date_Calc::dateNow('%d');
  775.         }
  776.         if ($month > 2) {
  777.             $month -= 2;
  778.         } else {
  779.             $month += 10;
  780.             $year--;
  781.         }
  782.  
  783.         $day = (floor((13 * $month - 1) / 5) +
  784.                 $day + ($year % 100) +
  785.                 floor(($year % 100) / 4) +
  786.                 floor(($year / 100) / 4) - 2 *
  787.                 floor($year / 100) + 77);
  788.  
  789.         $weekday_number = $day - 7 * floor($day / 7);
  790.         return $weekday_number;
  791.     }
  792.  
  793.     // }}}
  794.     // {{{ weekOfYear()
  795.  
  796.     /**
  797.      * Returns week of the year, first Sunday is first day of first week
  798.      *
  799.      * @param int    $day     the day of the month, default is current local day
  800.      * @param int    $month   the month, default is current local month
  801.      * @param int    $year    the year in four digit format, default is current local year
  802.      *
  803.      * @return int  the number of the week in the year
  804.      *
  805.      * @access public
  806.      * @static
  807.      */
  808.     function weekOfYear($day = 0, $month = 0, $year = 0)
  809.     {
  810.         if (empty($year)) {
  811.             $year = Date_Calc::dateNow('%Y');
  812.         }
  813.         if (empty($month)) {
  814.             $month = Date_Calc::dateNow('%m');
  815.         }
  816.         if (empty($day)) {
  817.             $day = Date_Calc::dateNow('%d');
  818.         }
  819.         $iso    = Date_Calc::gregorianToISO($day, $month, $year);
  820.         $parts  = explode('-', $iso);
  821.         $week_number = intval($parts[1]);
  822.         return $week_number;
  823.     }
  824.  
  825.     // }}}
  826.     // {{{ quarterOfYear()
  827.  
  828.     /**
  829.      * Returns quarter of the year for given date
  830.      *
  831.      * @param int    $day     the day of the month, default is current local day
  832.      * @param int    $month   the month, default is current local month
  833.      * @param int    $year    the year in four digit format, default is current local year
  834.      *
  835.      * @return int  the number of the quarter in the year
  836.      *
  837.      * @access public
  838.      * @static
  839.      */
  840.     function quarterOfYear($day = 0, $month = 0, $year = 0)
  841.     {
  842.         if (empty($year)) {
  843.             $year = Date_Calc::dateNow('%Y');
  844.         }
  845.         if (empty($month)) {
  846.             $month = Date_Calc::dateNow('%m');
  847.         }
  848.         if (empty($day)) {
  849.             $day = Date_Calc::dateNow('%d');
  850.         }
  851.         $year_quarter = intval(($month - 1) / 3 + 1);
  852.         return $year_quarter;
  853.     }
  854.  
  855.     // }}}
  856.     // {{{ daysInMonth()
  857.  
  858.     /**
  859.      * Find the number of days in the given month
  860.      *
  861.      * @param int    $month   the month, default is current local month
  862.      * @param int    $year    the year in four digit format, default is current local year
  863.      *
  864.      * @return int  the number of days the month has
  865.      *
  866.      * @access public
  867.      * @static
  868.      */
  869.     function daysInMonth($month = 0, $year = 0)
  870.     {
  871.         if (empty($year)) {
  872.             $year = Date_Calc::dateNow('%Y');
  873.         }
  874.         if (empty($month)) {
  875.             $month = Date_Calc::dateNow('%m');
  876.         }
  877.  
  878.         if ($year == 1582 && $month == 10) {
  879.             return 21;  // October 1582 only had 1st-4th and 15th-31st
  880.         }
  881.  
  882.         if ($month == 2) {
  883.             if (Date_Calc::isLeapYear($year)) {
  884.                 return 29;
  885.              } else {
  886.                 return 28;
  887.             }
  888.         } elseif ($month == 4 or $month == 6 or $month == 9 or $month == 11) {
  889.             return 30;
  890.         } else {
  891.             return 31;
  892.         }
  893.     }
  894.  
  895.     // }}}
  896.     // {{{ weeksInMonth()
  897.  
  898.     /**
  899.      * Returns the number of rows on a calendar month
  900.      *
  901.      * Useful for determining the number of rows when displaying a typical
  902.      * month calendar.
  903.      *
  904.      * @param int    $month   the month, default is current local month
  905.      * @param int    $year    the year in four digit format, default is current local year
  906.      *
  907.      * @return int  the number of weeks the month has
  908.      *
  909.      * @access public
  910.      * @static
  911.      */
  912.     function weeksInMonth($month = 0, $year = 0)
  913.     {
  914.         if (empty($year)) {
  915.             $year = Date_Calc::dateNow('%Y');
  916.         }
  917.         if (empty($month)) {
  918.             $month = Date_Calc::dateNow('%m');
  919.         }
  920.         $FDOM = Date_Calc::firstOfMonthWeekday($month, $year);
  921.         if (DATE_CALC_BEGIN_WEEKDAY==1 && $FDOM==0) {
  922.             $first_week_days = 7 - $FDOM + DATE_CALC_BEGIN_WEEKDAY;
  923.             $weeks = 1;
  924.         } elseif (DATE_CALC_BEGIN_WEEKDAY==0 && $FDOM == 6) {
  925.             $first_week_days = 7 - $FDOM + DATE_CALC_BEGIN_WEEKDAY;
  926.             $weeks = 1;
  927.         } else {
  928.             $first_week_days = DATE_CALC_BEGIN_WEEKDAY - $FDOM;
  929.             $weeks = 0;
  930.         }
  931.         $first_week_days %= 7;
  932.         return ceil((Date_Calc::daysInMonth($month, $year)
  933.                      - $first_week_days) / 7) + $weeks;
  934.     }
  935.  
  936.     // }}}
  937.     // {{{ getCalendarWeek()
  938.  
  939.     /**
  940.      * Return an array with days in week
  941.      *
  942.      * @param int    $day     the day of the month, default is current local day
  943.      * @param int    $month   the month, default is current local month
  944.      * @param int    $year    the year in four digit format, default is current local year
  945.      * @param string $format  the string indicating how to format the output
  946.      *
  947.      * @return array $week[$weekday]
  948.      *
  949.      * @access public
  950.      * @static
  951.      */
  952.     function getCalendarWeek($day = 0, $month = 0, $year = 0,
  953.                              $format = DATE_CALC_FORMAT)
  954.     {
  955.         if (empty($year)) {
  956.             $year = Date_Calc::dateNow('%Y');
  957.         }
  958.         if (empty($month)) {
  959.             $month = Date_Calc::dateNow('%m');
  960.         }
  961.         if (empty($day)) {
  962.             $day = Date_Calc::dateNow('%d');
  963.         }
  964.  
  965.         $week_array = array();
  966.  
  967.         // date for the column of week
  968.  
  969.         $curr_day = Date_Calc::beginOfWeek($day, $month, $year,'%E');
  970.  
  971.         for ($counter = 0; $counter <= 6; $counter++) {
  972.             $week_array[$counter] = Date_Calc::daysToDate($curr_day, $format);
  973.             $curr_day++;
  974.         }
  975.         return $week_array;
  976.     }
  977.  
  978.     // }}}
  979.     // {{{ getCalendarMonth()
  980.  
  981.     /**
  982.      * Return a set of arrays to construct a calendar month for the given date
  983.      *
  984.      * @param int    $month   the month, default is current local month
  985.      * @param int    $year    the year in four digit format, default is current local year
  986.      * @param string $format  the string indicating how to format the output
  987.      *
  988.      * @return array $month[$row][$col]
  989.      *
  990.      * @access public
  991.      * @static
  992.      */
  993.     function getCalendarMonth($month = 0, $year = 0,
  994.                               $format = DATE_CALC_FORMAT)
  995.     {
  996.         if (empty($year)) {
  997.             $year = Date_Calc::dateNow('%Y');
  998.         }
  999.         if (empty($month)) {
  1000.             $month = Date_Calc::dateNow('%m');
  1001.         }
  1002.  
  1003.         $month_array = array();
  1004.  
  1005.         // date for the first row, first column of calendar month
  1006.         if (DATE_CALC_BEGIN_WEEKDAY == 1) {
  1007.             if (Date_Calc::firstOfMonthWeekday($month, $year) == 0) {
  1008.                 $curr_day = Date_Calc::dateToDays('01', $month, $year) - 6;
  1009.             } else {
  1010.                 $curr_day = Date_Calc::dateToDays('01', $month, $year)
  1011.                     - Date_Calc::firstOfMonthWeekday($month, $year) + 1;
  1012.             }
  1013.         } else {
  1014.             $curr_day = (Date_Calc::dateToDays('01', $month, $year)
  1015.                 - Date_Calc::firstOfMonthWeekday($month, $year));
  1016.         }
  1017.  
  1018.         // number of days in this month
  1019.         $daysInMonth = Date_Calc::daysInMonth($month, $year);
  1020.  
  1021.         $weeksInMonth = Date_Calc::weeksInMonth($month, $year);
  1022.         for ($row_counter = 0; $row_counter < $weeksInMonth; $row_counter++) {
  1023.             for ($column_counter = 0; $column_counter <= 6; $column_counter++) {
  1024.                 $month_array[$row_counter][$column_counter] =
  1025.                         Date_Calc::daysToDate($curr_day , $format);
  1026.                 $curr_day++;
  1027.             }
  1028.         }
  1029.  
  1030.         return $month_array;
  1031.     }
  1032.  
  1033.     // }}}
  1034.     // {{{ getCalendarYear()
  1035.  
  1036.     /**
  1037.      * Return a set of arrays to construct a calendar year for the given date
  1038.      *
  1039.      * @param int    $year    the year in four digit format, default current local year
  1040.      * @param string $format  the string indicating how to format the output
  1041.      *
  1042.      * @return array $year[$month][$row][$col]
  1043.      *
  1044.      * @access public
  1045.      * @static
  1046.      */
  1047.     function getCalendarYear($year = 0, $format = DATE_CALC_FORMAT)
  1048.     {
  1049.         if (empty($year)) {
  1050.             $year = Date_Calc::dateNow('%Y');
  1051.         }
  1052.  
  1053.         $year_array = array();
  1054.  
  1055.         for ($curr_month = 0; $curr_month <= 11; $curr_month++) {
  1056.             $year_array[$curr_month] =
  1057.                     Date_Calc::getCalendarMonth($curr_month + 1,
  1058.                                                 $year, $format);
  1059.         }
  1060.  
  1061.         return $year_array;
  1062.     }
  1063.  
  1064.     // }}}
  1065.     // {{{ prevDay()
  1066.  
  1067.     /**
  1068.      * Returns date of day before given date
  1069.      *
  1070.      * @param int    $day     the day of the month, default is current local day
  1071.      * @param int    $month   the month, default is current local month
  1072.      * @param int    $year    the year in four digit format, default is current local year
  1073.      * @param string $format  the string indicating how to format the output
  1074.      *
  1075.      * @return string  the date in the desired format
  1076.      *
  1077.      * @access public
  1078.      * @static
  1079.      */
  1080.     function prevDay($day = 0, $month = 0, $year = 0,
  1081.                      $format = DATE_CALC_FORMAT)
  1082.     {
  1083.         if (empty($year)) {
  1084.             $year = Date_Calc::dateNow('%Y');
  1085.         }
  1086.         if (empty($month)) {
  1087.             $month = Date_Calc::dateNow('%m');
  1088.         }
  1089.         if (empty($day)) {
  1090.             $day = Date_Calc::dateNow('%d');
  1091.         }
  1092.         $days = Date_Calc::dateToDays($day, $month, $year);
  1093.         return Date_Calc::daysToDate($days - 1, $format);
  1094.     }
  1095.  
  1096.     // }}}
  1097.     // {{{ nextDay()
  1098.  
  1099.     /**
  1100.      * Returns date of day after given date
  1101.      *
  1102.      * @param int    $day     the day of the month, default is current local day
  1103.      * @param int    $month   the month, default is current local month
  1104.      * @param int    $year    the year in four digit format, default is current local year
  1105.      * @param string $format  the string indicating how to format the output
  1106.      *
  1107.      * @return string  the date in the desired format
  1108.      *
  1109.      * @access public
  1110.      * @static
  1111.      */
  1112.     function nextDay($day = 0, $month = 0, $year = 0,
  1113.                      $format = DATE_CALC_FORMAT)
  1114.     {
  1115.         if (empty($year)) {
  1116.             $year = Date_Calc::dateNow('%Y');
  1117.         }
  1118.         if (empty($month)) {
  1119.             $month = Date_Calc::dateNow('%m');
  1120.         }
  1121.         if (empty($day)) {
  1122.             $day = Date_Calc::dateNow('%d');
  1123.         }
  1124.         $days = Date_Calc::dateToDays($day, $month, $year);
  1125.         return Date_Calc::daysToDate($days + 1, $format);
  1126.     }
  1127.  
  1128.     // }}}
  1129.     // {{{ prevWeekday()
  1130.  
  1131.     /**
  1132.      * Returns date of the previous weekday, skipping from Monday to Friday
  1133.      *
  1134.      * @param int    $day     the day of the month, default is current local day
  1135.      * @param int    $month   the month, default is current local month
  1136.      * @param int    $year    the year in four digit format, default is current local year
  1137.      * @param string $format  the string indicating how to format the output
  1138.      *
  1139.      * @return string  the date in the desired format
  1140.      *
  1141.      * @access public
  1142.      * @static
  1143.      */
  1144.     function prevWeekday($day = 0, $month = 0, $year = 0,
  1145.                          $format = DATE_CALC_FORMAT)
  1146.     {
  1147.         if (empty($year)) {
  1148.             $year = Date_Calc::dateNow('%Y');
  1149.         }
  1150.         if (empty($month)) {
  1151.             $month = Date_Calc::dateNow('%m');
  1152.         }
  1153.         if (empty($day)) {
  1154.             $day = Date_Calc::dateNow('%d');
  1155.         }
  1156.         $days = Date_Calc::dateToDays($day, $month, $year);
  1157.         if (Date_Calc::dayOfWeek($day, $month, $year) == 1) {
  1158.             $days -= 3;
  1159.         } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 0) {
  1160.             $days -= 2;
  1161.         } else {
  1162.             $days -= 1;
  1163.         }
  1164.         return Date_Calc::daysToDate($days, $format);
  1165.     }
  1166.  
  1167.     // }}}
  1168.     // {{{ nextWeekday()
  1169.  
  1170.     /**
  1171.      * Returns date of the next weekday of given date, skipping from
  1172.      * Friday to Monday
  1173.      *
  1174.      * @param int    $day     the day of the month, default is current local day
  1175.      * @param int    $month   the month, default is current local month
  1176.      * @param int    $year    the year in four digit format, default is current local year
  1177.      * @param string $format  the string indicating how to format the output
  1178.      *
  1179.      * @return string  the date in the desired format
  1180.      *
  1181.      * @access public
  1182.      * @static
  1183.      */
  1184.     function nextWeekday($day = 0, $month = 0, $year = 0,
  1185.                          $format = DATE_CALC_FORMAT)
  1186.     {
  1187.         if (empty($year)) {
  1188.             $year = Date_Calc::dateNow('%Y');
  1189.         }
  1190.         if (empty($month)) {
  1191.             $month = Date_Calc::dateNow('%m');
  1192.         }
  1193.         if (empty($day)) {
  1194.             $day = Date_Calc::dateNow('%d');
  1195.         }
  1196.         $days = Date_Calc::dateToDays($day, $month, $year);
  1197.         if (Date_Calc::dayOfWeek($day, $month, $year) == 5) {
  1198.             $days += 3;
  1199.         } elseif (Date_Calc::dayOfWeek($day, $month, $year) == 6) {
  1200.             $days += 2;
  1201.         } else {
  1202.             $days += 1;
  1203.         }
  1204.         return Date_Calc::daysToDate($days, $format);
  1205.     }
  1206.  
  1207.     // }}}
  1208.     // {{{ prevDayOfWeek()
  1209.  
  1210.     /**
  1211.      * Returns date of the previous specific day of the week
  1212.      * from the given date
  1213.      *
  1214.      * @param int day of week, 0=Sunday
  1215.      * @param int    $day     the day of the month, default is current local day
  1216.      * @param int    $month   the month, default is current local month
  1217.      * @param int    $year    the year in four digit format, default is current local year
  1218.      * @param bool   $onOrBefore  if true and days are same, returns current day
  1219.      * @param string $format  the string indicating how to format the output
  1220.      *
  1221.      * @return string  the date in the desired format
  1222.      *
  1223.      * @access public
  1224.      * @static
  1225.      */
  1226.     function prevDayOfWeek($dow, $day = 0, $month = 0, $year = 0,
  1227.                            $format = DATE_CALC_FORMAT, $onOrBefore = false)
  1228.     {
  1229.         if (empty($year)) {
  1230.             $year = Date_Calc::dateNow('%Y');
  1231.         }
  1232.         if (empty($month)) {
  1233.             $month = Date_Calc::dateNow('%m');
  1234.         }
  1235.         if (empty($day)) {
  1236.             $day = Date_Calc::dateNow('%d');
  1237.         }
  1238.         $days = Date_Calc::dateToDays($day, $month, $year);
  1239.         $curr_weekday = Date_Calc::dayOfWeek($day, $month, $year);
  1240.         if ($curr_weekday == $dow) {
  1241.             if (!$onOrBefore) {
  1242.                 $days -= 7;
  1243.             }
  1244.         } elseif ($curr_weekday < $dow) {
  1245.             $days -= 7 - ($dow - $curr_weekday);
  1246.         } else {
  1247.             $days -= $curr_weekday - $dow;
  1248.         }
  1249.         return Date_Calc::daysToDate($days, $format);
  1250.     }
  1251.  
  1252.     // }}}
  1253.     // {{{ nextDayOfWeek()
  1254.  
  1255.     /**
  1256.      * Returns date of the next specific day of the week
  1257.      * from the given date
  1258.      *
  1259.      * @param int    $dow     the day of the week (0 = Sunday)
  1260.      * @param int    $day     the day of the month, default is current local day
  1261.      * @param int    $month   the month, default is current local month
  1262.      * @param int    $year    the year in four digit format, default is current local year
  1263.      * @param bool   $onOrAfter  if true and days are same, returns current day
  1264.      * @param string $format  the string indicating how to format the output
  1265.      *
  1266.      * @return string  the date in the desired format
  1267.      *
  1268.      * @access public
  1269.      * @static
  1270.      */
  1271.     function nextDayOfWeek($dow, $day = 0, $month = 0, $year = 0,
  1272.                            $format = DATE_CALC_FORMAT, $onOrAfter = false)
  1273.     {
  1274.         if (empty($year)) {
  1275.             $year = Date_Calc::dateNow('%Y');
  1276.         }
  1277.         if (empty($month)) {
  1278.             $month = Date_Calc::dateNow('%m');
  1279.         }
  1280.         if (empty($day)) {
  1281.             $day = Date_Calc::dateNow('%d');
  1282.         }
  1283.  
  1284.         $days = Date_Calc::dateToDays($day, $month, $year);
  1285.         $curr_weekday = Date_Calc::dayOfWeek($day, $month, $year);
  1286.  
  1287.         if ($curr_weekday == $dow) {
  1288.             if (!$onOrAfter) {
  1289.                 $days += 7;
  1290.             }
  1291.         } elseif ($curr_weekday > $dow) {
  1292.             $days += 7 - ($curr_weekday - $dow);
  1293.         } else {
  1294.             $days += $dow - $curr_weekday;
  1295.         }
  1296.  
  1297.         return Date_Calc::daysToDate($days, $format);
  1298.     }
  1299.  
  1300.     // }}}
  1301.     // {{{ prevDayOfWeekOnOrBefore()
  1302.  
  1303.     /**
  1304.      * Returns date of the previous specific day of the week
  1305.      * on or before the given date
  1306.      *
  1307.      * @param int    $dow     the day of the week (0 = Sunday)
  1308.      * @param int    $day     the day of the month, default is current local day
  1309.      * @param int    $month   the month, default is current local month
  1310.      * @param int    $year    the year in four digit format, default is current local year
  1311.      * @param string $format  the string indicating how to format the output
  1312.      *
  1313.      * @return string  the date in the desired format
  1314.      *
  1315.      * @access public
  1316.      * @static
  1317.      */
  1318.     function prevDayOfWeekOnOrBefore($dow, $day = 0, $month = 0, $year = 0,
  1319.                                      $format = DATE_CALC_FORMAT)
  1320.     {
  1321.         return Date_Calc::prevDayOfWeek($dow, $day, $month, $year, $format,
  1322.                                         true);
  1323.     }
  1324.  
  1325.     // }}}
  1326.     // {{{ nextDayOfWeekOnOrAfter()
  1327.  
  1328.     /**
  1329.      * Returns date of the next specific day of the week
  1330.      * on or after the given date
  1331.      *
  1332.      * @param int    $dow     the day of the week (0 = Sunday)
  1333.      * @param int    $day     the day of the month, default is current local day
  1334.      * @param int    $month   the month, default is current local month
  1335.      * @param int    $year    the year in four digit format, default is current local year
  1336.      * @param string $format  the string indicating how to format the output
  1337.      *
  1338.      * @return string  the date in the desired format
  1339.      *
  1340.      * @access public
  1341.      * @static
  1342.      */
  1343.     function nextDayOfWeekOnOrAfter($dow, $day = 0, $month = 0, $year = 0,
  1344.                                     $format = DATE_CALC_FORMAT)
  1345.     {
  1346.         return Date_Calc::nextDayOfWeek($dow, $day, $month, $year, $format,
  1347.                                         true);
  1348.     }
  1349.  
  1350.     // }}}
  1351.     // {{{ beginOfWeek()
  1352.  
  1353.     /**
  1354.      * Find the month day of the beginning of week for given date,
  1355.      * using DATE_CALC_BEGIN_WEEKDAY
  1356.      *
  1357.      * Can return weekday of prev month.
  1358.      *
  1359.      * @param int    $day     the day of the month, default is current local day
  1360.      * @param int    $month   the month, default is current local month
  1361.      * @param int    $year    the year in four digit format, default is current local year
  1362.      * @param string $format  the string indicating how to format the output
  1363.      *
  1364.      * @return string  the date in the desired format
  1365.      *
  1366.      * @access public
  1367.      * @static
  1368.      */
  1369.     function beginOfWeek($day = 0, $month = 0, $year = 0,
  1370.                          $format = DATE_CALC_FORMAT)
  1371.     {
  1372.         if (empty($year)) {
  1373.             $year = Date_Calc::dateNow('%Y');
  1374.         }
  1375.         if (empty($month)) {
  1376.             $month = Date_Calc::dateNow('%m');
  1377.         }
  1378.         if (empty($day)) {
  1379.             $day = Date_Calc::dateNow('%d');
  1380.         }
  1381.         $this_weekday = Date_Calc::dayOfWeek($day, $month, $year);
  1382.         $interval = (7 - DATE_CALC_BEGIN_WEEKDAY + $this_weekday) % 7;
  1383.         return Date_Calc::daysToDate(Date_Calc::dateToDays($day, $month, $year)
  1384.                                      - $interval, $format);
  1385.     }
  1386.  
  1387.     // }}}
  1388.     // {{{ endOfWeek()
  1389.  
  1390.     /**
  1391.      * Find the month day of the end of week for given date,
  1392.      * using DATE_CALC_BEGIN_WEEKDAY
  1393.      *
  1394.      * Can return weekday of following month.
  1395.      *
  1396.      * @param int    $day     the day of the month, default is current local day
  1397.      * @param int    $month   the month, default is current local month
  1398.      * @param int    $year    the year in four digit format, default is current local year
  1399.      * @param string $format  the string indicating how to format the output
  1400.      *
  1401.      * @return string  the date in the desired format
  1402.      *
  1403.      * @access public
  1404.      * @static
  1405.      */
  1406.     function endOfWeek($day = 0, $month = 0, $year = 0,
  1407.                        $format = DATE_CALC_FORMAT)
  1408.     {
  1409.         if (empty($year)) {
  1410.             $year = Date_Calc::dateNow('%Y');
  1411.         }
  1412.         if (empty($month)) {
  1413.             $month = Date_Calc::dateNow('%m');
  1414.         }
  1415.         if (empty($day)) {
  1416.             $day = Date_Calc::dateNow('%d');
  1417.         }
  1418.         $this_weekday = Date_Calc::dayOfWeek($day, $month, $year);
  1419.         $interval = (6 + DATE_CALC_BEGIN_WEEKDAY - $this_weekday) % 7;
  1420.         return Date_Calc::daysToDate(Date_Calc::dateToDays($day, $month, $year)
  1421.                                      + $interval, $format);
  1422.     }
  1423.  
  1424.     // }}}
  1425.     // {{{ beginOfPrevWeek()
  1426.  
  1427.     /**
  1428.      * Find the month day of the beginning of week before given date,
  1429.      * using DATE_CALC_BEGIN_WEEKDAY
  1430.      *
  1431.      * Can return weekday of prev month.
  1432.      *
  1433.      * @param int    $day     the day of the month, default is current local day
  1434.      * @param int    $month   the month, default is current local month
  1435.      * @param int    $year    the year in four digit format, default is current local year
  1436.      * @param string $format  the string indicating how to format the output
  1437.      *
  1438.      * @return string  the date in the desired format
  1439.      *
  1440.      * @access public
  1441.      * @static
  1442.      */
  1443.     function beginOfPrevWeek($day = 0, $month = 0, $year = 0,
  1444.                              $format = DATE_CALC_FORMAT)
  1445.     {
  1446.         if (empty($year)) {
  1447.             $year = Date_Calc::dateNow('%Y');
  1448.         }
  1449.         if (empty($month)) {
  1450.             $month = Date_Calc::dateNow('%m');
  1451.         }
  1452.         if (empty($day)) {
  1453.             $day = Date_Calc::dateNow('%d');
  1454.         }
  1455.  
  1456.         $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day-7,
  1457.                                                             $month,
  1458.                                                             $year),
  1459.                                       '%Y%m%d');
  1460.  
  1461.         $prev_week_year  = substr($date, 0, 4);
  1462.         $prev_week_month = substr($date, 4, 2);
  1463.         $prev_week_day   = substr($date, 6, 2);
  1464.  
  1465.         return Date_Calc::beginOfWeek($prev_week_day, $prev_week_month,
  1466.                                       $prev_week_year, $format);
  1467.     }
  1468.  
  1469.     // }}}
  1470.     // {{{ beginOfNextWeek()
  1471.  
  1472.     /**
  1473.      * Find the month day of the beginning of week after given date,
  1474.      * using DATE_CALC_BEGIN_WEEKDAY
  1475.      *
  1476.      * Can return weekday of prev month.
  1477.      *
  1478.      * @param int    $day     the day of the month, default is current local day
  1479.      * @param int    $month   the month, default is current local month
  1480.      * @param int    $year    the year in four digit format, default is current local year
  1481.      * @param string $format  the string indicating how to format the output
  1482.      *
  1483.      * @return string  the date in the desired format
  1484.      *
  1485.      * @access public
  1486.      * @static
  1487.      */
  1488.     function beginOfNextWeek($day = 0, $month = 0, $year = 0,
  1489.                              $format = DATE_CALC_FORMAT)
  1490.     {
  1491.         if (empty($year)) {
  1492.             $year = Date_Calc::dateNow('%Y');
  1493.         }
  1494.         if (empty($month)) {
  1495.             $month = Date_Calc::dateNow('%m');
  1496.         }
  1497.         if (empty($day)) {
  1498.             $day = Date_Calc::dateNow('%d');
  1499.         }
  1500.  
  1501.         $date = Date_Calc::daysToDate(Date_Calc::dateToDays($day + 7,
  1502.                                                             $month,
  1503.                                                             $year),
  1504.                                       '%Y%m%d');
  1505.  
  1506.         $next_week_year  = substr($date, 0, 4);
  1507.         $next_week_month = substr($date, 4, 2);
  1508.         $next_week_day   = substr($date, 6, 2);
  1509.  
  1510.         return Date_Calc::beginOfWeek($next_week_day, $next_week_month,
  1511.                                       $next_week_year, $format);
  1512.     }
  1513.  
  1514.     // }}}
  1515.     // {{{ beginOfMonth()
  1516.  
  1517.     /**
  1518.      * Return date of first day of month of given date
  1519.      *
  1520.      * @param int    $month   the month, default is current local month
  1521.      * @param int    $year    the year in four digit format, default is current local year
  1522.      * @param string $format  the string indicating how to format the output
  1523.      *
  1524.      * @return string  the date in the desired format
  1525.      *
  1526.      * @access public
  1527.      * @static
  1528.      * @see Date_Calc::beginOfMonthBySpan()
  1529.      * @deprecated Method deprecated in Release 1.4.4
  1530.      */
  1531.     function beginOfMonth($month = 0, $year = 0, $format = DATE_CALC_FORMAT)
  1532.     {
  1533.         if (empty($year)) {
  1534.             $year = Date_Calc::dateNow('%Y');
  1535.         }
  1536.         if (empty($month)) {
  1537.             $month = Date_Calc::dateNow('%m');
  1538.         }
  1539.         return Date_Calc::dateFormat('01', $month, $year, $format);
  1540.     }
  1541.  
  1542.     // }}}
  1543.     // {{{ beginOfPrevMonth()
  1544.  
  1545.     /**
  1546.      * Returns date of the first day of previous month of given date
  1547.      *
  1548.      * @param int    $day     the day of the month, default is current local day
  1549.      * @param int    $month   the month, default is current local month
  1550.      * @param int    $year    the year in four digit format, default is current local year
  1551.      * @param string $format  the string indicating how to format the output
  1552.      *
  1553.      * @return string  the date in the desired format
  1554.      *
  1555.      * @access public
  1556.      * @static
  1557.      * @see Date_Calc::beginOfMonthBySpan()
  1558.      * @deprecated Method deprecated in Release 1.4.4
  1559.      */
  1560.     function beginOfPrevMonth($day = 0, $month = 0, $year = 0,
  1561.                               $format = DATE_CALC_FORMAT)
  1562.     {
  1563.         if (empty($year)) {
  1564.             $year = Date_Calc::dateNow('%Y');
  1565.         }
  1566.         if (empty($month)) {
  1567.             $month = Date_Calc::dateNow('%m');
  1568.         }
  1569.         if (empty($day)) {
  1570.             $day = Date_Calc::dateNow('%d');
  1571.         }
  1572.         if ($month > 1) {
  1573.             $month--;
  1574.             $day = 1;
  1575.         } else {
  1576.             $year--;
  1577.             $month = 12;
  1578.             $day   = 1;
  1579.         }
  1580.         return Date_Calc::dateFormat($day, $month, $year, $format);
  1581.     }
  1582.  
  1583.     // }}}
  1584.     // {{{ endOfPrevMonth()
  1585.  
  1586.     /**
  1587.      * Returns date of the last day of previous month for given date
  1588.      *
  1589.      * @param int    $day     the day of the month, default is current local day
  1590.      * @param int    $month   the month, default is current local month
  1591.      * @param int    $year    the year in four digit format, default is current local year
  1592.      * @param string $format  the string indicating how to format the output
  1593.      *
  1594.      * @return string  the date in the desired format
  1595.      *
  1596.      * @access public
  1597.      * @static
  1598.      * @see Date_Calc::endOfMonthBySpan()
  1599.      * @deprecated Method deprecated in Release 1.4.4
  1600.      */
  1601.     function endOfPrevMonth($day = 0, $month = 0, $year = 0,
  1602.                             $format = DATE_CALC_FORMAT)
  1603.     {
  1604.         if (empty($year)) {
  1605.             $year = Date_Calc::dateNow('%Y');
  1606.         }
  1607.         if (empty($month)) {
  1608.             $month = Date_Calc::dateNow('%m');
  1609.         }
  1610.         if (empty($day)) {
  1611.             $day = Date_Calc::dateNow('%d');
  1612.         }
  1613.         if ($month > 1) {
  1614.             $month--;
  1615.         } else {
  1616.             $year--;
  1617.             $month = 12;
  1618.         }
  1619.         $day = Date_Calc::daysInMonth($month, $year);
  1620.         return Date_Calc::dateFormat($day, $month, $year, $format);
  1621.     }
  1622.  
  1623.     // }}}
  1624.     // {{{ beginOfNextMonth()
  1625.  
  1626.     /**
  1627.      * Returns date of begin of next month of given date
  1628.      *
  1629.      * @param int    $day     the day of the month, default is current local day
  1630.      * @param int    $month   the month, default is current local month
  1631.      * @param int    $year    the year in four digit format, default is current local year
  1632.      * @param string $format  the string indicating how to format the output
  1633.      *
  1634.      * @return string  the date in the desired format
  1635.      *
  1636.      * @access public
  1637.      * @static
  1638.      * @see Date_Calc::beginOfMonthBySpan()
  1639.      * @deprecated Method deprecated in Release 1.4.4
  1640.      */
  1641.     function beginOfNextMonth($day = 0, $month = 0, $year = 0,
  1642.                               $format = DATE_CALC_FORMAT)
  1643.     {
  1644.         if (empty($year)) {
  1645.             $year = Date_Calc::dateNow('%Y');
  1646.         }
  1647.         if (empty($month)) {
  1648.             $month = Date_Calc::dateNow('%m');
  1649.         }
  1650.         if (empty($day)) {
  1651.             $day = Date_Calc::dateNow('%d');
  1652.         }
  1653.         if ($month < 12) {
  1654.             $month++;
  1655.             $day = 1;
  1656.         } else {
  1657.             $year++;
  1658.             $month = 1;
  1659.             $day = 1;
  1660.         }
  1661.         return Date_Calc::dateFormat($day, $month, $year, $format);
  1662.     }
  1663.  
  1664.     // }}}
  1665.     // {{{ endOfNextMonth()
  1666.  
  1667.     /**
  1668.      * Returns date of the last day of next month of given date
  1669.      *
  1670.      * @param int    $day     the day of the month, default is current local day
  1671.      * @param int    $month   the month, default is current local month
  1672.      * @param int    $year    the year in four digit format, default is current local year
  1673.      * @param string $format  the string indicating how to format the output
  1674.      *
  1675.      * @return string  the date in the desired format
  1676.      *
  1677.      * @access public
  1678.      * @static
  1679.      * @see Date_Calc::endOfMonthBySpan()
  1680.      * @deprecated Method deprecated in Release 1.4.4
  1681.      */
  1682.     function endOfNextMonth($day = 0, $month = 0, $year = 0,
  1683.                             $format = DATE_CALC_FORMAT)
  1684.     {
  1685.         if (empty($year)) {
  1686.             $year = Date_Calc::dateNow('%Y');
  1687.         }
  1688.         if (empty($month)) {
  1689.             $month = Date_Calc::dateNow('%m');
  1690.         }
  1691.         if (empty($day)) {
  1692.             $day = Date_Calc::dateNow('%d');
  1693.         }
  1694.         if ($month < 12) {
  1695.             $month++;
  1696.         } else {
  1697.             $year++;
  1698.             $month = 1;
  1699.         }
  1700.         $day = Date_Calc::daysInMonth($month, $year);
  1701.         return Date_Calc::dateFormat($day, $month, $year, $format);
  1702.     }
  1703.  
  1704.     // }}}
  1705.     // {{{ beginOfMonthBySpan()
  1706.  
  1707.     /**
  1708.      * Returns date of the first day of the month in the number of months
  1709.      * from the given date
  1710.      *
  1711.      * @param int    $months  the number of months from the date provided.
  1712.      *                         Positive numbers go into the future.
  1713.      *                         Negative numbers go into the past.
  1714.      *                         0 is the month presented in $month.
  1715.      * @param string $month   the month, default is current local month
  1716.      * @param string $year    the year in four digit format, default is the
  1717.      *                         current local year
  1718.      * @param string $format  the string indicating how to format the output
  1719.      *
  1720.      * @return string  the date in the desired format
  1721.      *
  1722.      * @access public
  1723.      * @static
  1724.      * @since  Method available since Release 1.4.4
  1725.      */
  1726.     function beginOfMonthBySpan($months = 0, $month = 0, $year = 0,
  1727.                                 $format = DATE_CALC_FORMAT)
  1728.     {
  1729.         if (empty($year)) {
  1730.             $year = Date_Calc::dateNow('%Y');
  1731.         }
  1732.         if (empty($month)) {
  1733.             $month = Date_Calc::dateNow('%m');
  1734.         }
  1735.         if ($months > 0) {
  1736.             // future month
  1737.             $tmp_mo = $month + $months;
  1738.             $month  = $tmp_mo % 12;
  1739.             if ($month == 0) {
  1740.                 $month = 12;
  1741.                 $year = $year + floor(($tmp_mo - 1) / 12);
  1742.             } else {
  1743.                 $year = $year + floor($tmp_mo / 12);
  1744.             }
  1745.         } else {
  1746.             // past or present month
  1747.             $tmp_mo = $month + $months;
  1748.             if ($tmp_mo > 0) {
  1749.                 // same year
  1750.                 $month = $tmp_mo;
  1751.             } elseif ($tmp_mo == 0) {
  1752.                 // prior dec
  1753.                 $month = 12;
  1754.                 $year--;
  1755.             } else {
  1756.                 // some time in a prior year
  1757.                 $month = 12 + ($tmp_mo % 12);
  1758.                 $year  = $year + floor($tmp_mo / 12);
  1759.             }
  1760.         }
  1761.         return Date_Calc::dateFormat(1, $month, $year, $format);
  1762.     }
  1763.  
  1764.     // }}}
  1765.     // {{{ endOfMonthBySpan()
  1766.  
  1767.     /**
  1768.      * Returns date of the last day of the month in the number of months
  1769.      * from the given date
  1770.      *
  1771.      * @param int    $months  the number of months from the date provided.
  1772.      *                         Positive numbers go into the future.
  1773.      *                         Negative numbers go into the past.
  1774.      *                         0 is the month presented in $month.
  1775.      * @param string $month   the month, default is current local month
  1776.      * @param string $year    the year in four digit format, default is the
  1777.      *                         current local year
  1778.      * @param string $format  the string indicating how to format the output
  1779.      *
  1780.      * @return string  the date in the desired format
  1781.      *
  1782.      * @access public
  1783.      * @static
  1784.      * @since  Method available since Release 1.4.4
  1785.      */
  1786.     function endOfMonthBySpan($months = 0, $month = 0, $year = 0,
  1787.                               $format = DATE_CALC_FORMAT)
  1788.     {
  1789.         if (empty($year)) {
  1790.             $year = Date_Calc::dateNow('%Y');
  1791.         }
  1792.         if (empty($month)) {
  1793.             $month = Date_Calc::dateNow('%m');
  1794.         }
  1795.         if ($months > 0) {
  1796.             // future month
  1797.             $tmp_mo = $month + $months;
  1798.             $month  = $tmp_mo % 12;
  1799.             if ($month == 0) {
  1800.                 $month = 12;
  1801.                 $year = $year + floor(($tmp_mo - 1) / 12);
  1802.             } else {
  1803.                 $year = $year + floor($tmp_mo / 12);
  1804.             }
  1805.         } else {
  1806.             // past or present month
  1807.             $tmp_mo = $month + $months;
  1808.             if ($tmp_mo > 0) {
  1809.                 // same year
  1810.                 $month = $tmp_mo;
  1811.             } elseif ($tmp_mo == 0) {
  1812.                 // prior dec
  1813.                 $month = 12;
  1814.                 $year--;
  1815.             } else {
  1816.                 // some time in a prior year
  1817.                 $month = 12 + ($tmp_mo % 12);
  1818.                 $year  = $year + floor($tmp_mo / 12);
  1819.             }
  1820.         }
  1821.         return Date_Calc::dateFormat(Date_Calc::daysInMonth($month, $year),
  1822.                                      $month, $year, $format);
  1823.     }
  1824.  
  1825.     // }}}
  1826.     // {{{ firstOfMonthWeekday()
  1827.  
  1828.     /**
  1829.      * Find the day of the week for the first of the month of given date
  1830.      *
  1831.      * @param int    $month   the month, default is current local month
  1832.      * @param int    $year    the year in four digit format, default is current local year
  1833.      *
  1834.      * @return int number of weekday for the first day, 0=Sunday
  1835.      *
  1836.      * @access public
  1837.      * @static
  1838.      */
  1839.     function firstOfMonthWeekday($month = 0, $year = 0)
  1840.     {
  1841.         if (empty($year)) {
  1842.             $year = Date_Calc::dateNow('%Y');
  1843.         }
  1844.         if (empty($month)) {
  1845.             $month = Date_Calc::dateNow('%m');
  1846.         }
  1847.         return Date_Calc::dayOfWeek('01', $month, $year);
  1848.     }
  1849.  
  1850.     // }}}
  1851.     // {{{ NWeekdayOfMonth()
  1852.  
  1853.     /**
  1854.      * Calculates the date of the Nth weekday of the month,
  1855.      * such as the second Saturday of January 2000
  1856.      *
  1857.      * @param int    $week    the number of the week to get
  1858.      *                         (1 = first, etc.  Also can be 'last'.)
  1859.      * @param int    $dow     the day of the week (0 = Sunday)
  1860.      * @param int    $month   the month
  1861.      * @param int    $year    the year.  Use the complete year instead of the
  1862.      *                         abbreviated version.  E.g. use 2005, not 05.
  1863.      *                         Do not add leading 0's for years prior to 1000.
  1864.      * @param string $format  the string indicating how to format the output
  1865.      *
  1866.      * @return string  the date in the desired format
  1867.      *
  1868.      * @access public
  1869.      * @static
  1870.      */
  1871.     function NWeekdayOfMonth($week, $dow, $month, $year,
  1872.                              $format = DATE_CALC_FORMAT)
  1873.     {
  1874.         if (is_numeric($week)) {
  1875.             $DOW1day = ($week - 1) * 7 + 1;
  1876.             $DOW1    = Date_Calc::dayOfWeek($DOW1day, $month, $year);
  1877.             $wdate   = ($week - 1) * 7 + 1 + (7 + $dow - $DOW1) % 7;
  1878.             if ($wdate > Date_Calc::daysInMonth($month, $year)) {
  1879.                 return -1;
  1880.             } else {
  1881.                 return Date_Calc::dateFormat($wdate, $month, $year, $format);
  1882.             }
  1883.         } elseif ($week == 'last' && $dow < 7) {
  1884.             $lastday = Date_Calc::daysInMonth($month, $year);
  1885.             $lastdow = Date_Calc::dayOfWeek($lastday, $month, $year);
  1886.             $diff    = $dow - $lastdow;
  1887.             if ($diff > 0) {
  1888.                 return Date_Calc::dateFormat($lastday - (7 - $diff), $month,
  1889.                                              $year, $format);
  1890.             } else {
  1891.                 return Date_Calc::dateFormat($lastday + $diff, $month,
  1892.                                              $year, $format);
  1893.             }
  1894.         } else {
  1895.             return -1;
  1896.         }
  1897.     }
  1898.  
  1899.     // }}}
  1900.     // {{{ isValidDate()
  1901.  
  1902.     /**
  1903.      * Returns true for valid date, false for invalid date
  1904.      *
  1905.      * @param int    $day     the day of the month
  1906.      * @param int    $month   the month
  1907.      * @param int    $year    the year.  Use the complete year instead of the
  1908.      *                         abbreviated version.  E.g. use 2005, not 05.
  1909.      *                         Do not add leading 0's for years prior to 1000.
  1910.      *
  1911.      * @return boolean
  1912.      *
  1913.      * @access public
  1914.      * @static
  1915.      */
  1916.     function isValidDate($day, $month, $year)
  1917.     {
  1918.         if ($year < 0 || $year > 9999) {
  1919.             return false;
  1920.         }
  1921.         if (!checkdate($month, $day, $year)) {
  1922.             return false;
  1923.         }
  1924.         return true;
  1925.     }
  1926.  
  1927.     // }}}
  1928.     // {{{ isLeapYear()
  1929.  
  1930.     /**
  1931.      * Returns true for a leap year, else false
  1932.      *
  1933.      * @param int    $year    the year.  Use the complete year instead of the
  1934.      *                         abbreviated version.  E.g. use 2005, not 05.
  1935.      *                         Do not add leading 0's for years prior to 1000.
  1936.      *
  1937.      * @return boolean
  1938.      *
  1939.      * @access public
  1940.      * @static
  1941.      */
  1942.     function isLeapYear($year = 0)
  1943.     {
  1944.         if (empty($year)) {
  1945.             $year = Date_Calc::dateNow('%Y');
  1946.         }
  1947.         if (preg_match('/\D/', $year)) {
  1948.             return false;
  1949.         }
  1950.         if ($year < 1000) {
  1951.             return false;
  1952.         }
  1953.         if ($year < 1582) {
  1954.             // pre Gregorio XIII - 1582
  1955.             return ($year % 4 == 0);
  1956.         } else {
  1957.             // post Gregorio XIII - 1582
  1958.             return (($year % 4 == 0) && ($year % 100 != 0)) || ($year % 400 == 0);
  1959.         }
  1960.     }
  1961.  
  1962.     // }}}
  1963.     // {{{ isFutureDate()
  1964.  
  1965.     /**
  1966.      * Determines if given date is a future date from now
  1967.      *
  1968.      * @param int    $day     the day of the month
  1969.      * @param int    $month   the month
  1970.      * @param int    $year    the year.  Use the complete year instead of the
  1971.      *                         abbreviated version.  E.g. use 2005, not 05.
  1972.      *                         Do not add leading 0's for years prior to 1000.
  1973.      *
  1974.      * @return boolean
  1975.      *
  1976.      * @access public
  1977.      * @static
  1978.      */
  1979.     function isFutureDate($day, $month, $year)
  1980.     {
  1981.         $this_year  = Date_Calc::dateNow('%Y');
  1982.         $this_month = Date_Calc::dateNow('%m');
  1983.         $this_day   = Date_Calc::dateNow('%d');
  1984.  
  1985.         if ($year > $this_year) {
  1986.             return true;
  1987.         } elseif ($year == $this_year) {
  1988.             if ($month > $this_month) {
  1989.                 return true;
  1990.             } elseif ($month == $this_month) {
  1991.                 if ($day > $this_day) {
  1992.                     return true;
  1993.                 }
  1994.             }
  1995.         }
  1996.         return false;
  1997.     }
  1998.  
  1999.     // }}}
  2000.     // {{{ isPastDate()
  2001.  
  2002.     /**
  2003.      * Determines if given date is a past date from now
  2004.      *
  2005.      * @param int    $day     the day of the month
  2006.      * @param int    $month   the month
  2007.      * @param int    $year    the year.  Use the complete year instead of the
  2008.      *                         abbreviated version.  E.g. use 2005, not 05.
  2009.      *                         Do not add leading 0's for years prior to 1000.
  2010.      *
  2011.      * @return boolean
  2012.      *
  2013.      * @access public
  2014.      * @static
  2015.      */
  2016.     function isPastDate($day, $month, $year)
  2017.     {
  2018.         $this_year  = Date_Calc::dateNow('%Y');
  2019.         $this_month = Date_Calc::dateNow('%m');
  2020.         $this_day   = Date_Calc::dateNow('%d');
  2021.  
  2022.         if ($year < $this_year) {
  2023.             return true;
  2024.         } elseif ($year == $this_year) {
  2025.             if ($month < $this_month) {
  2026.                 return true;
  2027.             } elseif ($month == $this_month) {
  2028.                 if ($day < $this_day) {
  2029.                     return true;
  2030.                 }
  2031.             }
  2032.         }
  2033.         return false;
  2034.     }
  2035.  
  2036.     // }}}
  2037.     // {{{ dateDiff()
  2038.  
  2039.     /**
  2040.      * Returns number of days between two given dates
  2041.      *
  2042.      * @param int    $day1    the day of the month
  2043.      * @param int    $month1  the month
  2044.      * @param int    $year1   the year.  Use the complete year instead of the
  2045.      *                         abbreviated version.  E.g. use 2005, not 05.
  2046.      *                         Do not add leading 0's for years prior to 1000.
  2047.      * @param int    $day2    the day of the month
  2048.      * @param int    $month2  the month
  2049.      * @param int    $year2   the year.  Use the complete year instead of the
  2050.      *                         abbreviated version.  E.g. use 2005, not 05.
  2051.      *                         Do not add leading 0's for years prior to 1000.
  2052.      *
  2053.      * @return int  the absolute number of days between the two dates.
  2054.      *               If an error occurs, -1 is returned.
  2055.      *
  2056.      * @access public
  2057.      * @static
  2058.      */
  2059.     function dateDiff($day1, $month1, $year1, $day2, $month2, $year2)
  2060.     {
  2061.         if (!Date_Calc::isValidDate($day1, $month1, $year1)) {
  2062.             return -1;
  2063.         }
  2064.         if (!Date_Calc::isValidDate($day2, $month2, $year2)) {
  2065.             return -1;
  2066.         }
  2067.         return abs(Date_Calc::dateToDays($day1, $month1, $year1)
  2068.                    - Date_Calc::dateToDays($day2, $month2, $year2));
  2069.     }
  2070.  
  2071.     // }}}
  2072.     // {{{ compareDates()
  2073.  
  2074.     /**
  2075.      * Compares two dates
  2076.      *
  2077.      * @param int    $day1    the day of the month
  2078.      * @param int    $month1  the month
  2079.      * @param int    $year1   the year.  Use the complete year instead of the
  2080.      *                         abbreviated version.  E.g. use 2005, not 05.
  2081.      *                         Do not add leading 0's for years prior to 1000.
  2082.      * @param int    $day2    the day of the month
  2083.      * @param int    $month2  the month
  2084.      * @param int    $year2   the year.  Use the complete year instead of the
  2085.      *                         abbreviated version.  E.g. use 2005, not 05.
  2086.      *                         Do not add leading 0's for years prior to 1000.
  2087.      *
  2088.      * @return int  0 if the dates are equal. 1 if date 1 is later, -1 if
  2089.      *               date 1 is earlier.
  2090.      *
  2091.      * @access public
  2092.      * @static
  2093.      */
  2094.     function compareDates($day1, $month1, $year1, $day2, $month2, $year2)
  2095.     {
  2096.         $ndays1 = Date_Calc::dateToDays($day1, $month1, $year1);
  2097.         $ndays2 = Date_Calc::dateToDays($day2, $month2, $year2);
  2098.         if ($ndays1 == $ndays2) {
  2099.             return 0;
  2100.         }
  2101.         return ($ndays1 > $ndays2) ? 1 : -1;
  2102.     }
  2103.  
  2104.     // }}}
  2105. }
  2106.  
  2107. // }}}
  2108.  
  2109. /*
  2110.  * Local variables:
  2111.  * mode: php
  2112.  * tab-width: 4
  2113.  * c-basic-offset: 4
  2114.  * c-hanging-comment-ender-p: nil
  2115.  * End:
  2116.  */
  2117. ?>