kernel
[ class tree: kernel ] [ index: kernel ] [ all elements ]

Source for file BitDate.php

Documentation is available at BitDate.php

  1. <?php
  2. /**
  3.  * Date Handling Class
  4.  *
  5.  * @package kernel
  6.  * @version $Header$
  7.  *
  8.  *  Created by: Jeremy Jongsma (jjongsma@tickchat.com)
  9.  *  Created on: Sat Jul 26 11:51:31 CDT 2003
  10.  */
  11.  
  12. /**
  13.  * BitDate
  14.  *
  15.  * This class takes care of all time/date conversions for
  16.  * storing dates in the DB and displaying dates to the user.
  17.  *
  18.  * The objectives are:
  19.  *  - Dates will always stored in UTC in the database
  20.  *  - Display dates will be computed based on the preferred
  21.  *    display offset specified in the constructor
  22.  *
  23.  * @package kernel
  24.  *
  25.  * @todo As of 1.7, dates are still stored in server local time.
  26.  *  This should be changed for 1.7.1 (requires many module changes).
  27.  */
  28. class BitDate {
  29.     /**
  30.      * UTC offset to use for display
  31.      * @var int 
  32.      */
  33.     var $display_offset;
  34.  
  35.     /**
  36.      * Current UTC offset of server
  37.      * @var int 
  38.      */
  39.     var $server_offset;
  40.  
  41.     /**
  42.      * Default constructor
  43.      * @param int desired offset for date display, in minutes
  44.      */
  45.     function BitDate($_display_offset 0{
  46.         if version_comparephpversion()"5.1.0"">=" ) ) {
  47.             date_default_timezone_set@date_default_timezone_get() );
  48.         }
  49.         $this->display_offset = $_display_offset;
  50.         $this->server_offset = mktime(0,0,0,1,2,1970gmmktime(0,0,0,1,2,1970);
  51.     }
  52.  
  53.     /**
  54.      * Retrieves the user's preferred offset for displaying dates.
  55.      *
  56.      * @param int the logged-in user.
  57.      * @return int the preferred offset to UTC or 0 for straight UTC display
  58.      */
  59.     function get_display_offset($_user false{
  60.         global $gBitUser;
  61.  
  62.         // Cache preference from DB
  63.         $display_tz "UTC";
  64.  
  65.         // Default to UTC get_display_offset
  66.         $this->display_offset = 0;
  67.  
  68.         // Load pref from DB if cache is empty
  69.         $display_tz $gBitUser->getPreference('site_display_utc'"Local");
  70.  
  71.         // Recompute offset each request in case DST kicked in
  72.         if $display_tz == "Local" && isset($_COOKIE["tz_offset"]))
  73.             $this->display_offset = intval($_COOKIE["tz_offset"]);
  74.         else if $display_tz == "Fixed" )
  75.             $this->display_offset = $gBitUser->getPreference'site_display_timezone')
  76.             if version_comparephpversion()"5.1.0"">=" and !is_numeric$this->display_offset ) ) {
  77.                 $dateTimeZoneUser new DateTimeZone$this->display_offset );
  78.                 $dtNow new DateTime"now" );
  79.                 $this->display_offset = $dateTimeZoneUser->getOffset$dtNow );
  80.             }
  81.         return $this->display_offset;
  82.     }
  83.  
  84.     /**
  85.      * Convert a UTC timestamp to the preferred display offset.
  86.      * @param timestamp ISO format date
  87.      *     yYYY-mM-dD hH:mM:sS.s ( Lower case letters optional, but should be 0 )
  88.      * @return int Seconds count based on 1st Jan 1970<br>
  89.      */
  90.     function getDisplayDateFromUTC($_timestamp{
  91.         global $gBitUser;
  92.         
  93.         if $gBitUser->getPreference('site_display_utc'"Local"== "Fixed" && class_exists'DateTime' ) ) {
  94.             date_default_timezone_set$gBitUser->getPreference'site_display_timezone''UTC' ) );
  95.             if is_numeric$_timestamp )) {
  96.                 $dateTimeUser new DateTime'@'.$_timestamp );
  97.             else  {
  98.                 $dateTimeUser new DateTime$_timestamp );
  99.             }
  100.             $dateTimeUserZone new DateTimeZone$gBitUser->getPreference'site_display_timezone''UTC' ) );
  101.             return strtotime$dateTimeUser->format(DATE_ATOM) ) timezone_offset_get$dateTimeUserZone$dateTimeUser );
  102.         else {
  103.             return $this->getTimestampFromISO($_timestamp$this->display_offset;
  104.         }
  105.     }
  106.  
  107.     /**
  108.      * Convert a display-offset timestamp to UTC.
  109.      * @param timestamp ISO format date
  110.      *     yYYY-mM-dD hH:mM:sS.s ( Lower case letters optional, but should be 0 )
  111.      * @return int Seconds count based on 1st Jan 1970<br>
  112.      */
  113.     function getUTCFromDisplayDate($_timestamp{
  114.         global $gBitUser;
  115.         
  116.         if $gBitUser->getPreference('site_display_utc'"Local"== "Fixed" {
  117.             date_default_timezone_set$gBitUser->getPreference'site_display_timezone''UTC' ) );
  118.             if is_numeric$_timestamp )) {
  119.                 $dateTimeUser new DateTime'@'.$_timestamp );
  120.             else  {
  121.                 $dateTimeUser new DateTime$_timestamp );
  122.             }
  123.             $dateTimeUserZone new DateTimeZone$gBitUser->getPreference'site_display_timezone''UTC' ) );
  124.             return strtotime$dateTimeUser->format(DATE_ATOM) ) timezone_offset_get$dateTimeUserZone$dateTimeUser );
  125.         else {
  126.             return $this->getTimestampFromISO($_timestamp$this->display_offset;
  127.         }
  128.     }
  129.  
  130.     /**
  131.      * Convert a UTC timestamp to the local server time.
  132.      * @param  timestamp UTC timestamp to convert.
  133.      * @return timestamp Server timestamp.
  134.      */
  135.     function getServerDateFromUTC($_timestamp{
  136.         return $this->getTimestampFromISO($_timestamp$this->server_offset;
  137.     }
  138.  
  139.     /**
  140.      * Convert a local server timestamp to UTC.
  141.      * @param  timestamp Server timestamp to convert.
  142.      * @return timestamp UTC timestamp.
  143.      */
  144.     function getUTCFromServerDate($_timestamp{
  145.         return $this->getTimestampFromISO($_timestamp$this->server_offset;
  146.     }
  147.  
  148.     /**
  149.      * Retrieve a current UTC timestamp as Unix epoch.
  150.      * @return int Unix epoch
  151.      */
  152.     function getUTCTime({
  153.         return time();
  154.     }
  155.  
  156.     /**
  157.      * Retrieve a current UTC Timestamp as an ISO formated date/time.
  158.      * @return string Current ISO formated date/time
  159.      */
  160.     function getUTCTimestamp({
  161.         return $this->date("Y-m-d H:i:s",time(),true);
  162.     }
  163.  
  164.     /**
  165.      * Retrieve a current UTC Date as an ISO formated date
  166.      * @return string Current ISO formated date
  167.      */
  168.     function getUTCDate({
  169.         return $this->date("Y-m-d",time(),true);
  170.     }
  171.  
  172.     /**
  173.      * Get the name of the current timezone.
  174.      * Currently, only "UTC" or an empty string (Local).
  175.      * @return string Current timezone
  176.      */
  177.     function getTzName({
  178.         if ($this->display_offset == 0)
  179.             return "UTC";
  180.         else
  181.             return "";
  182.     }
  183.  
  184.     /**
  185.      * Convert ISO date to numberic timestamp.
  186.      *
  187.      * @param string ISO format date
  188.      *     yYYY-mM-dD hH:mM:sS.s ( Lower case letters optional, but should be 0 )
  189.      * @return int Seconds count based on 1st Jan 1970<br>
  190.      *  returns $iso_date if it is a number, or 0 if format invalid
  191.      */
  192.     function getTimestampFromISO$iso_date$reverse false {
  193.         $ret 0;
  194.         if is_numeric($iso_date) ) 
  195.             $ret $iso_date;
  196.         else if $reverse {
  197.             // Input d.m.y, h:m:s
  198.             if (preg_match(
  199.                 "|^([0-9]{1,2})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{3,4}), ?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,8}))?|",
  200.                 ($iso_date)$rr)) {
  201.                     if (!isset($rr[5])) $ret $this->gmmktime(0,0,0,$rr[2],$rr[1],$rr[3]);
  202.                     else $ret @$this->gmmktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[1],$rr[3]);
  203.                 }
  204.         else {    
  205.                 // Input y.m.d h:m:s
  206.                 if (preg_match(
  207.                     "|^([0-9]{3,4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
  208.                     ($iso_date)$rr)) {
  209.                         if (!isset($rr[5])) $ret $this->gmmktime(0,0,0,$rr[2],$rr[3],$rr[1]);
  210.                         else $ret @$this->gmmktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
  211.             }
  212.         }
  213.         return $ret;
  214.     }
  215.  
  216.     /**
  217.      * Returns day of week, 0 = Sunday,... 6=Saturday.
  218.      * Algorithm from PEAR::Date_Calc
  219.      * @param int 
  220.      * @param int 
  221.      * @param int 
  222.      * @return int 
  223.      */
  224.     function dayOfWeek($year$month$day)
  225.     {
  226.     /*
  227.     Pope Gregory removed 10 days - October 5 to October 14 - from the year 1582 and
  228.     proclaimed that from that time onwards 3 days would be dropped from the calendar
  229.     every 400 years.
  230.  
  231.     Thursday, October 4, 1582 (Julian) was followed immediately by Friday, October 15, 1582 (Gregorian).
  232.     */
  233.         if ($year <= 1582{
  234.             if ($year 1582 ||
  235.                 ($year == 1582 && ($month 10 || ($month == 10 && $day 15)))) $greg_correction 3;
  236.              else
  237.                 $greg_correction 0;
  238.         else
  239.             $greg_correction 0;
  240.  
  241.         if($month 2)
  242.             $month -= 2;
  243.         else {
  244.             $month += 10;
  245.             $year--;
  246.         }
  247.  
  248.         $day =  floor((13 $month 15+
  249.             $day ($year 100+
  250.             floor(($year 1004+
  251.             floor(($year 1004*
  252.             floor($year 10077 $greg_correction;
  253.  
  254.         return $day floor($day 7);
  255.     }
  256.  
  257.     /**
  258.      *    Returns week of year, 1 = first week of year.
  259.      *    Algorithm from PEAR::Date_Calc
  260.      * This needs to be checked out for both start day and early date rules
  261.      * @param int 
  262.      * @param int 
  263.      * @param int 
  264.      * @return int 
  265.      */
  266.     function weekOfYear($year$month$day)
  267.     {
  268.         $iso    $this->gregorianToISO($year$month$day);
  269.         $parts  explode('-',$iso);
  270.         $week_number intval($parts[1]);
  271.         if $week_number == $week_number 53;
  272.         return $week_number;
  273.     }
  274.  
  275.     /**
  276.      * Checks for leap year, returns true if it is. No 2-digit year check. Also
  277.      * handles julian calendar correctly.
  278.      * @param int 
  279.      * @return boolean 
  280.      */
  281.     function _is_leap_year($year)
  282.     {
  283.         if ($year != 0return false;
  284.  
  285.         if ($year 400 == 0{
  286.             return true;
  287.         // if gregorian calendar (>1582), century not-divisible by 400 is not leap
  288.         else if ($year 1582 && $year 100 == {
  289.             return false;
  290.         }
  291.  
  292.         return true;
  293.     }
  294.  
  295.     /**
  296.      * checks for leap year, returns true if it is. Has 2-digit year check
  297.      * @param int 
  298.      * @return boolean 
  299.      */
  300.     function is_leap_year($year)
  301.     {
  302.         return  $this->_is_leap_year($this->year_digit_check($year));
  303.     }
  304.  
  305.     /**
  306.      * Fix 2-digit years. Works for any century.
  307.      * Assumes that if 2-digit is more than 30 years in future, then previous century.
  308.      * @todo This needs to be disabled when dates prior to 100AD are required in ISO format
  309.      * @param int 
  310.      * @return int 
  311.      */
  312.     function year_digit_check($y)
  313.     {
  314.         if ($y 100{
  315.  
  316.             $yr = (integer) date("Y");
  317.             $century = (integer) ($yr /100);
  318.  
  319.             if ($yr%100 50{
  320.                 $c1 $century 1;
  321.                 $c0 $century;
  322.             else {
  323.                 $c1 $century;
  324.                 $c0 $century 1;
  325.             }
  326.             $c1 *= 100;
  327.             // if 2-digit year is less than 30 years in future, set it to this century
  328.             // otherwise if more than 30 years in future, then we set 2-digit year to the prev century.
  329.             if (($y $c1$yr+30$y $y $c1;
  330.             else $y $y $c0*100;
  331.         }
  332.         return $y;
  333.     }
  334.  
  335.     /**
  336.      *Returns an array with date info.
  337.      * @param boolean 
  338.      * @param boolean 
  339.      * @return array 
  340.      */
  341.     function getDate($d=false,$fast=false)
  342.     {
  343.         if ($d === falsereturn $this->getdate();
  344.         if ((abs($d<= 0x7FFFFFFF)) // check if number in 32-bit signed range
  345.             if (!defined('ADODB_NO_NEGATIVE_TS'|| $d >= 0// if windows, must be +ve integer
  346.                 return @$this->_getDate($d);
  347.         }
  348.         return $this->_getDate($d,$fast);
  349.     }
  350.  
  351.     /*
  352.      * generate $YRS table for _adodb_getdate()
  353.      *
  354.     function _date_gentable($out=true)
  355.     {
  356.  
  357.         for ($i=1970; $i >= 1600; $i-=10) {
  358.             $s = adodb_gmmktime(0,0,0,1,1,$i);
  359.             echo "$i => $s,<br>";
  360.         }
  361.     }
  362.     adodb_date_gentable();
  363.  
  364.     for ($i=1970; $i > 1500; $i--) {
  365.  
  366.     echo "<hr>$i ";
  367.         adodb_date_test_date($i,1,1);
  368.     }
  369.  
  370.     */
  371.  
  372.     /**
  373.      * Low-level function that returns the getdate() array. We have a special
  374.      * $fast flag, which if set to true, will return fewer array values,
  375.      * and is much faster as it does not calculate dow, etc.
  376.      * @param int Date to be converted in Unix epochs
  377.      * @param boolean Return short format array ( less weekday and month )
  378.      * @param boolean Ignore timezone
  379.      * @return array 
  380.      */
  381.     function _getDate($origd=false,$fast=false,$is_gmt=false)
  382.     {
  383.         static $YRS;
  384.  
  385.         $d =  $origd ($is_gmt adodb_get_gmt_diff(false,false,false));
  386.  
  387.         $_day_power 86400;
  388.         $_hour_power 3600;
  389.         $_min_power 60;
  390.  
  391.         if ($d < -12219321600$d -= 86400*10// if 15 Oct 1582 or earlier, gregorian correction
  392.  
  393.         $_month_table_normal array("",31,28,31,30,31,30,31,31,30,31,30,31);
  394.         $_month_table_leaf array("",31,29,31,30,31,30,31,31,30,31,30,31);
  395.  
  396.         $d366 $_day_power 366;
  397.         $d365 $_day_power 365;
  398.  
  399.         if ($d 0{
  400.  
  401.             if (empty($YRS)) $YRS array(
  402.                 1970 => 0,
  403.                 1960 => -315619200,
  404.                 1950 => -631152000,
  405.                 1940 => -946771200,
  406.                 1930 => -1262304000,
  407.                 1920 => -1577923200,
  408.                 1910 => -1893456000,
  409.                 1900 => -2208988800,
  410.                 1890 => -2524521600,
  411.                 1880 => -2840140800,
  412.                 1870 => -3155673600,
  413.                 1860 => -3471292800,
  414.                 1850 => -3786825600,
  415.                 1840 => -4102444800,
  416.                 1830 => -4417977600,
  417.                 1820 => -4733596800,
  418.                 1810 => -5049129600,
  419.                 1800 => -5364662400,
  420.                 1790 => -5680195200,
  421.                 1780 => -5995814400,
  422.                 1770 => -6311347200,
  423.                 1760 => -6626966400,
  424.                 1750 => -6942499200,
  425.                 1740 => -7258118400,
  426.                 1730 => -7573651200,
  427.                 1720 => -7889270400,
  428.                 1710 => -8204803200,
  429.                 1700 => -8520336000,
  430.                 1690 => -8835868800,
  431.                 1680 => -9151488000,
  432.                 1670 => -9467020800,
  433.                 1660 => -9782640000,
  434.                 1650 => -10098172800,
  435.                 1640 => -10413792000,
  436.                 1630 => -10729324800,
  437.                 1620 => -11044944000,
  438.                 1610 => -11360476800,
  439.                 1600 => -11676096000);
  440.  
  441.             if ($is_gmt$origd $d;
  442.             // The valid range of a 32bit signed timestamp is typically from
  443.             // Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT
  444.             //
  445.  
  446.             $lastsecs 0;
  447.             $lastyear 1970;
  448.             foreach($YRS as $year => $secs{
  449.                 if ($d >= $secs{
  450.                     $a $lastyear;
  451.                     break;
  452.                 }
  453.                 $lastsecs $secs;
  454.                 $lastyear $year;
  455.             }
  456.  
  457.             $d -= $lastsecs;
  458.             if (!isset($a)) $a $lastyear;
  459.  
  460.             for (--$a >= 0;{
  461.                 $lastd $d;
  462.  
  463.                 if ($leaf _adodb_is_leap_year($a)) $d += $d366;
  464.                 else $d += $d365;
  465.  
  466.                 if ($d >= 0{
  467.                     $year $a;
  468.                     break;
  469.                 }
  470.             }
  471.  
  472.             $secsInYear 86400 ($leaf 366 365$lastd;
  473.  
  474.             $d $lastd;
  475.             $mtab ($leaf$_month_table_leaf $_month_table_normal;
  476.             for ($a 13 --$a 0;{
  477.                 $lastd $d;
  478.                 $d += $mtab[$a$_day_power;
  479.                 if ($d >= 0{
  480.                     $month $a;
  481.                     $ndays $mtab[$a];
  482.                     break;
  483.                 }
  484.             }
  485.  
  486.             $d $lastd;
  487.             $day $ndays ceil(($d+1($_day_power));
  488.  
  489.             $d += ($ndays $day+1)$_day_power;
  490.             $hour floor($d/$_hour_power);
  491.  
  492.         else {
  493.             for ($a 1970 ;; $a++{
  494.                 $lastd $d;
  495.  
  496.                 if ($leaf _adodb_is_leap_year($a)) $d -= $d366;
  497.                 else $d -= $d365;
  498.                 if ($d 0{
  499.                     $year $a;
  500.                     break;
  501.                 }
  502.             }
  503.             $secsInYear $lastd;
  504.             $d $lastd;
  505.             $mtab ($leaf$_month_table_leaf $_month_table_normal;
  506.             for ($a $a <= 12$a++{
  507.                 $lastd $d;
  508.                 $d -= $mtab[$a$_day_power;
  509.                 if ($d 0{
  510.                     $month $a;
  511.                     $ndays $mtab[$a];
  512.                     break;
  513.                 }
  514.             }
  515.             $d $lastd;
  516.             $day ceil(($d+1$_day_power);
  517.             $d $d ($day-1$_day_power;
  518.             $hour floor($d /$_hour_power);
  519.         }
  520.  
  521.         $d -= $hour $_hour_power;
  522.         $min floor($d/$_min_power);
  523.         $secs $d $min $_min_power;
  524.         if ($fast{
  525.             return array(
  526.             'seconds' => $secs,
  527.             'minutes' => $min,
  528.             'hours' => $hour,
  529.             'mday' => $day,
  530.             'mon' => $month,
  531.             'year' => $year,
  532.             'yday' => floor($secsInYear/$_day_power),
  533.             'leap' => $leaf,
  534.             'ndays' => $ndays
  535.             );
  536.         }
  537.  
  538.  
  539.         $dow adodb_dow($year,$month,$day);
  540.  
  541.         return array(
  542.             'seconds' => $secs,
  543.             'minutes' => $min,
  544.             'hours' => $hour,
  545.             'mday' => $day,
  546.             'wday' => $dow,
  547.             'mon' => $month,
  548.             'year' => $year,
  549.             'yday' => floor($secsInYear/$_day_power),
  550.             'weekday' => gmdate('l',$_day_power*(3+$dow)),
  551.             'month' => gmdate('F',mktime(0,0,0,$month,2,1971)),
  552.             => $origd
  553.         );
  554.     }
  555.  
  556.     /*
  557.      * Accepts unix timestamp and iso date format
  558.      * ISO format date is converted into unix timestamp before calling date()
  559.      * @param string Format of date output
  560.      * @param int/string Date to be converted
  561.      * @param boolean Ignore timezone
  562.      * @return string In the format specified by $fmt
  563.      */
  564.     function date2($fmt$d=false$is_gmt=false)
  565.     {    if is_numeric($d) ) $this->date($fmt,$d,$is_gmt);
  566.  
  567.         if ($d !== false{
  568.             if (!preg_match(
  569.                 "|^([0-9]{3,4})[-/\.]?([0-9]{1,2})[-/\.]?([0-9]{1,2})[ -]?(([0-9]{1,2}):?([0-9]{1,2}):?([0-9\.]{1,4}))?|",
  570.                 ($d)$rr)) return $this->date($fmt,false,$is_gmt);
  571.  
  572.             if ($rr[1<= 100 && $rr[2]<= 1return adodb_date($fmt,false,$is_gmt);
  573.  
  574.             // h-m-s-MM-DD-YY
  575.             if (!isset($rr[5])) $d adodb_mktime(0,0,0,$rr[2],$rr[3],$rr[1]);
  576.             else $d @adodb_mktime($rr[5],$rr[6],$rr[7],$rr[2],$rr[3],$rr[1]);
  577.         }
  578.  
  579.         return $this->date($fmt,$d,$is_gmt);
  580.     }
  581.  
  582.  
  583.     /**
  584.      * Return formatted date based on timestamp $d
  585.      * @param string Format of date output
  586.      * @param int Date to be converted
  587.      * @param boolean Ignore timezone
  588.      * @return string In the format specified by $fmt
  589.      */
  590.     function date($fmt,$d=false,$is_gmt=false)
  591.     {
  592.     static $daylight;
  593.         if ($d === falsereturn ($is_gmt)@gmdate($fmt)@date($fmt);
  594.             if ((abs($d<= 0x7FFFFFFF)) // check if number in 32-bit signed range
  595.                 if (!defined('ADODB_NO_NEGATIVE_TS'|| $d >= 0// if windows, must be +ve integer
  596.                     return ($is_gmt)@gmdate($fmt,$d)@date($fmt,$d);
  597.         }
  598.         $_day_power 86400;
  599.  
  600.         $arr $this->_getdate($d,true,$is_gmt);
  601.  
  602. //        if (!isset($daylight)) $daylight = function_exists('adodb_daylight_sv');
  603. //        if ($daylight) adodb_daylight_sv($arr, $is_gmt);
  604.  
  605.         $year $arr['year'];
  606.         $month $arr['mon'];
  607.         $day $arr['mday'];
  608.         $hour $arr['hours'];
  609.         $min $arr['minutes'];
  610.         $secs $arr['seconds'];
  611.  
  612.         $max strlen($fmt);
  613.         $dates '';
  614.  
  615.         /*
  616.             at this point, we have the following integer vars to manipulate:
  617.             $year, $month, $day, $hour, $min, $secs
  618.         */
  619.         for ($i=0$i $max$i++{
  620.             switch($fmt[$i]{
  621.             case 'T'$dates .= date('T');break;
  622.             // YEAR
  623.             case 'L'$dates .= $arr['leap''1' '0'break;
  624.             case 'r'// Thu, 21 Dec 2000 16:01:07 +0200
  625.  
  626.                 // 4.3.11 uses '04 Jun 2004'
  627.                 // 4.3.8 uses  ' 4 Jun 2004'
  628.                 $dates .= gmdate('D',$_day_power*(3+$this->dow($year,$month,$day))).', '
  629.                     . ($day<10?'0'.$day:$day' '.date('M',mktime(0,0,0,$month,2,1971)).' '.$year.' ';
  630.  
  631.                 if ($hour 10$dates .= '0'.$hourelse $dates .= $hour;
  632.  
  633.                 if ($min 10$dates .= ':0'.$minelse $dates .= ':'.$min;
  634.  
  635.                 if ($secs 10$dates .= ':0'.$secselse $dates .= ':'.$secs;
  636.  
  637.                 $gmt adodb_get_gmt_diff();
  638.                 $dates .= sprintf(' %s%04d',($gmt<0)?'+':'-',abs($gmt)/36)break;
  639.  
  640.             case 'Y'$dates .= $yearbreak;
  641.             case 'y'$dates .= substr($year,strlen($year)-2,2)break;
  642.             // MONTH
  643.             case 'm'if ($month<10$dates .= '0'.$monthelse $dates .= $monthbreak;
  644.             case 'Q'$dates .= ($month+3)>>2break;
  645.             case 'n'$dates .= $monthbreak;
  646.             case 'M'$dates .= date('M',mktime(0,0,0,$month,2,1971))break;
  647.             case 'F'$dates .= date('F',mktime(0,0,0,$month,2,1971))break;
  648.             // DAY
  649.             case 't'$dates .= $arr['ndays']break;
  650.             case 'z'$dates .= $arr['yday']break;
  651.             case 'w'$dates .= adodb_dow($year,$month,$day)break;
  652.             case 'l'$dates .= gmdate('l',$_day_power*(3+adodb_dow($year,$month,$day)))break;
  653.             case 'D'$dates .= gmdate('D',$_day_power*(3+adodb_dow($year,$month,$day)))break;
  654.             case 'j'$dates .= $daybreak;
  655.             case 'd'if ($day<10$dates .= '0'.$dayelse $dates .= $daybreak;
  656.             case 'S':
  657.                 $d10 $day 10;
  658.                 if ($d10 == 1$dates .= 'st';
  659.                 else if ($d10 == && $day != 12$dates .= 'nd';
  660.                 else if ($d10 == 3$dates .= 'rd';
  661.                 else $dates .= 'th';
  662.                 break;
  663.  
  664.             // HOUR
  665.             case 'Z':
  666.                 $dates .= ($is_gmt: -adodb_get_gmt_diff()break;
  667.             case 'O':
  668.                 $gmt ($is_gmtadodb_get_gmt_diff();
  669.                 $dates .= sprintf('%s%04d',($gmt<0)?'+':'-',abs($gmt)/36)break;
  670.  
  671.             case 'H':
  672.                 if ($hour 10$dates .= '0'.$hour;
  673.                 else $dates .= $hour;
  674.                 break;
  675.             case 'h':
  676.                 if ($hour 12$hh $hour 12;
  677.                 else {
  678.                     if ($hour == 0$hh '12';
  679.                     else $hh $hour;
  680.                 }
  681.  
  682.                 if ($hh 10$dates .= '0'.$hh;
  683.                 else $dates .= $hh;
  684.                 break;
  685.  
  686.             case 'G':
  687.                 $dates .= $hour;
  688.                 break;
  689.  
  690.             case 'g':
  691.                 if ($hour 12$hh $hour 12;
  692.                 else {
  693.                     if ($hour == 0$hh '12';
  694.                     else $hh $hour;
  695.                 }
  696.                 $dates .= $hh;
  697.                 break;
  698.             // MINUTES
  699.             case 'i'if ($min 10$dates .= '0'.$minelse $dates .= $minbreak;
  700.             // SECONDS
  701.             case 'U'$dates .= $dbreak;
  702.             case 's'if ($secs 10$dates .= '0'.$secselse $dates .= $secsbreak;
  703.             // AM/PM
  704.             // Note 00:00 to 11:59 is AM, while 12:00 to 23:59 is PM
  705.             case 'a':
  706.                 if ($hour>=12$dates .= 'pm';
  707.                 else $dates .= 'am';
  708.                 break;
  709.             case 'A':
  710.                 if ($hour>=12$dates .= 'PM';
  711.                 else $dates .= 'AM';
  712.                 break;
  713.             default:
  714.                 $dates .= $fmt[$i]break;
  715.             // ESCAPE
  716.             case "\\":
  717.                 $i++;
  718.                 if ($i $max$dates .= $fmt[$i];
  719.                 break;
  720.             }
  721.         }
  722.         return $dates;
  723.     }
  724.  
  725.     /**
  726.      * Returns a timestamp given a GMT/UTC time.
  727.      * @param int Hour
  728.      * @param int Minute
  729.      * @param int Second
  730.      * @param int Month
  731.      * @param int Day
  732.      * @param int Year
  733.      * @param int $is_dst is not implemented and is ignored
  734.      * @return int 
  735.      */
  736.     function gmmktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false)
  737.     {
  738.         return $this->mktime($hr,$min,$sec,$mon,$day,$year,$is_dst,true);
  739.     }
  740.  
  741.     /**
  742.      * Return a timestamp given a local time. Originally by jackbbs.
  743.      * Not a very fast algorithm - O(n) operation. Could be optimized to O(1).
  744.      * @param int Hour
  745.      * @param int Minute
  746.      * @param int Second
  747.      * @param int Month
  748.      * @param int Day
  749.      * @param int Year
  750.      * @param int $is_dst is not implemented and is ignored
  751.      * @return int 
  752.      */
  753.     function mktime($hr,$min,$sec,$mon=false,$day=false,$year=false,$is_dst=false,$is_gmt=false)
  754.     {
  755.         if ($mon === false{
  756.             return $is_gmt@gmmktime($hr,$min,$sec)@mktime($hr,$min,$sec);
  757.  
  758. /* Need to check if this can be deleted
  759.             // for windows, we don't check 1970 because with timezone differences,
  760.             // 1 Jan 1970 could generate negative timestamp, which is illegal
  761.             if (1971 < $year && $year < 2038
  762.                 || !defined('ADODB_NO_NEGATIVE_TS') && (1901 < $year && $year < 2038)
  763.                 ) {
  764.                     return $is_gmt ?
  765.                         @gmmktime($hr,$min,$sec,$mon,$day,$year):
  766.                         @mktime($hr,$min,$sec,$mon,$day,$year);
  767.                 }
  768. */
  769.         }
  770.  
  771.         $gmt_different ($is_gmt$this->server_offset;
  772.  
  773.         /*
  774.         # disabled because some people place large values in $sec.
  775.         # however we need it for $mon because we use an array...
  776.         $hr = intval($hr);
  777.         $min = intval($min);
  778.         $sec = intval($sec);
  779.         */
  780.         $mon intval($mon);
  781.         $day intval($day);
  782.         $year intval($year);
  783.  
  784.  
  785.         $year $this->year_digit_check($year);
  786.  
  787.         if ($mon 12{
  788.             $y floor($mon 12);
  789.             $year += $y;
  790.             $mon -= $y*12;
  791.         }
  792.         else if $mon <= {
  793.             $mon += 12;
  794.             $year -= 1;
  795.         }
  796.         
  797.         $_day_power 86400;
  798.         $_hour_power 3600;
  799.         $_min_power 60;
  800.  
  801.         $_month_table_normal array("",31,28,31,30,31,30,31,31,30,31,30,31);
  802.         $_month_table_leaf array("",31,29,31,30,31,30,31,31,30,31,30,31);
  803.  
  804.         $_total_date 0;
  805.         if ($year >= 1970{
  806.             for ($a 1970 $a <= $year$a++{
  807.                 $leaf _adodb_is_leap_year($a);
  808.                 if ($leaf == true{
  809.                     $loop_table $_month_table_leaf;
  810.                     $_add_date 366;
  811.                 else {
  812.                     $loop_table $_month_table_normal;
  813.                     $_add_date 365;
  814.                 }
  815.                 if ($a $year{
  816.                     $_total_date += $_add_date;
  817.                 else {
  818.                     for($b=1;$b<$mon;$b++{
  819.                         $_total_date += $loop_table[$b];
  820.                     }
  821.                 }
  822.             }
  823.             $_total_date +=$day-1;
  824.             $ret $_total_date $_day_power $hr $_hour_power $min $_min_power $sec $gmt_different;
  825.  
  826.         else {
  827.             for ($a 1969 $a >= $year$a--{
  828.                 $leaf _adodb_is_leap_year($a);
  829.                 if ($leaf == true{
  830.                     $loop_table $_month_table_leaf;
  831.                     $_add_date 366;
  832.                 else {
  833.                     $loop_table $_month_table_normal;
  834.                     $_add_date 365;
  835.                 }
  836.                 if ($a $year$_total_date += $_add_date;
  837.                 else {
  838.                     for($b=12;$b>$mon;$b--{
  839.                         $_total_date += $loop_table[$b];
  840.                     }
  841.                 }
  842.             }
  843.             $_total_date += $loop_table[$mon$day;
  844.  
  845.             $_day_time $hr $_hour_power $min $_min_power $sec;
  846.             $_day_time $_day_power $_day_time;
  847.             $ret = -$_total_date $_day_power $_day_time $gmt_different);
  848.             if ($ret < -12220185600$ret += 10*86400// if earlier than 5 Oct 1582 - gregorian correction
  849.             else if ($ret < -12219321600$ret = -12219321600// if in limbo, reset to 15 Oct 1582.
  850.         }
  851.         //print " dmy=$day/$mon/$year $hr:$min:$sec => " .$ret;
  852.         return $ret;
  853.     }
  854.  
  855.     function gmstrftime($fmt$ls=false)
  856.     {
  857.         return strftime($fmt,$ls,true);
  858.     }
  859.  
  860.     function strtotime($time$now=NULL)
  861.     {
  862.         if($now == NULL
  863.             return strtotime($time);
  864.         else
  865.             return strtotime($time$now);
  866.     }
  867.  
  868.     // hack - convert to adodb_date
  869.     function strftime($fmt$ls=false,$is_gmt=false)
  870.     {
  871.     global $ADODB_DATE_LOCALE;
  872.  
  873.         if ((abs($ls<= 0x7FFFFFFF)) // check if number in 32-bit signed range
  874.             if (!defined('ADODB_NO_NEGATIVE_TS'|| $ls >= 0// if windows, must be +ve integer
  875.                 return ($is_gmt)@gmstrftime($fmt,$ls)@strftime($fmt,$ls);
  876.         }
  877.  
  878.         if (empty($ADODB_DATE_LOCALE)) {
  879.             $tstr strtoupper(gmstrftime('%c',31366800))// 30 Dec 1970, 1 am
  880.             $sep substr($tstr,2,1);
  881.             $hasAM strrpos($tstr,'M'!== false;
  882.  
  883.             $ADODB_DATE_LOCALE array();
  884.             $ADODB_DATE_LOCALE[=  strncmp($tstr,'30',2== 'd'.$sep.'m'.$sep.'y' 'm'.$sep.'d'.$sep.'y';
  885.             $ADODB_DATE_LOCALE[]  ($hasAM'h:i:s a' 'H:i:s';
  886.  
  887.         }
  888.         $inpct false;
  889.         $fmtdate '';
  890.         for ($i=0,$max strlen($fmt)$i $max$i++{
  891.             $ch $fmt[$i];
  892.             if ($ch == '%'{
  893.                 if ($inpct{
  894.                     $fmtdate .= '%';
  895.                     $inpct false;
  896.                 else
  897.                     $inpct true;
  898.             else if ($inpct{
  899.  
  900.                 $inpct false;
  901.                 switch($ch{
  902.                 case '0':
  903.                 case '1':
  904.                 case '2':
  905.                 case '3':
  906.                 case '4':
  907.                 case '5':
  908.                 case '6':
  909.                 case '7':
  910.                 case '8':
  911.                 case '9':
  912.                 case 'E':
  913.                 case 'O':
  914.                     /* ignore format modifiers */
  915.                     $inpct true;
  916.                     break;
  917.  
  918.                 case 'a'$fmtdate .= 'D'break;
  919.                 case 'A'$fmtdate .= 'l'break;
  920.                 case 'h':
  921.                 case 'b'$fmtdate .= 'M'break;
  922.                 case 'B'$fmtdate .= 'F'break;
  923.                 case 'c'$fmtdate .= $ADODB_DATE_LOCALE[0].$ADODB_DATE_LOCALE[1]break;
  924.                 case 'C'$fmtdate .= '\C?'break// century
  925.                 case 'd'$fmtdate .= 'd'break;
  926.                 case 'D'$fmtdate .= 'm/d/y'break;
  927.                 case 'e'$fmtdate .= 'j'break;
  928.                 case 'g'$fmtdate .= '\g?'break//?
  929.                 case 'G'$fmtdate .= '\G?'break//?
  930.                 case 'H'$fmtdate .= 'H'break;
  931.                 case 'I'$fmtdate .= 'h'break;
  932.                 case 'j'$fmtdate .= '?z'$parsej truebreak// wrong as j=1-based, z=0-basd
  933.                 case 'm'$fmtdate .= 'm'break;
  934.                 case 'M'$fmtdate .= 'i'break;
  935.                 case 'n'$fmtdate .= "\n"break;
  936.                 case 'p'$fmtdate .= 'a'break;
  937.                 case 'r'$fmtdate .= 'h:i:s a'break;
  938.                 case 'R'$fmtdate .= 'H:i:s'break;
  939.                 case 'S'$fmtdate .= 's'break;
  940.                 case 't'$fmtdate .= "\t"break;
  941.                 case 'T'$fmtdate .= 'H:i:s'break;
  942.                 case 'u'$fmtdate .= '?u'$parseu truebreak// wrong strftime=1-based, date=0-basde
  943.                 case 'U'$fmtdate .= '?U'$parseU truebreak;// wrong strftime=1-based, date=0-based
  944.                 case 'x'$fmtdate .= $ADODB_DATE_LOCALE[0]break;
  945.                 case 'X'$fmtdate .= $ADODB_DATE_LOCALE[1]break;
  946.                 case 'w'$fmtdate .= '?w'$parseu truebreak// wrong strftime=1-based, date=0-basde
  947.                 case 'W'$fmtdate .= '?W'$parseU truebreak;// wrong strftime=1-based, date=0-based
  948.                 case 'y'$fmtdate .= 'y'break;
  949.                 case 'Y'$fmtdate .= 'Y'break;
  950.                 case 'Z'$fmtdate .= 'T'break;
  951.                 }
  952.             else if (('A' <= ($ch&& ($ch<= 'Z' || ('a' <= ($ch&& ($ch<= 'z' ))
  953.                 $fmtdate .= "\\".$ch;
  954.             else
  955.                 $fmtdate .= $ch;
  956.         }
  957.         //echo "fmt=",$fmtdate,"<br>";
  958.         if ($ls === false$ls time();
  959.         $ret $this->date($fmtdate$ls$is_gmt);
  960.         return $ret;
  961.     }
  962.  
  963.     /**
  964.      * Converts from Gregorian Year-Month-Day to ISO YearNumber-WeekNumber-WeekDay
  965.      *
  966.      * Uses ISO 8601 definitions.
  967.      * Algorithm from Rick McCarty, 1999 at http://personal.ecu.edu/mccartyr/ISOwdALG.txt
  968.      *
  969.      * @param int $year 
  970.      * @param int $month 
  971.      * @param int $day 
  972.      * @return string 
  973.      * @access public
  974.      */
  975.     // Transcribed to PHP by Jesus M. Castagnetto (blame him if it is fubared ;-)
  976.     function gregorianToISO($year$month$day{
  977.         $mnth array (0,31,59,90,120,151,181,212,243,273,304,334);
  978.         if ($month == 0{
  979.             $year--;
  980.             $month 12;
  981.         }
  982.         $y_isleap $this->is_leap_year($year);
  983.         $y_1_isleap $this->is_leap_year($year 1);
  984.  
  985.         $day_of_year_number $day $mnth[$month 1];
  986.         if ($y_isleap && $month 2{
  987.             $day_of_year_number++;
  988.         }
  989.         // find Jan 1 weekday (monday = 1, sunday = 7)
  990.         $yy ($year 1100;
  991.         $c ($year 1$yy;
  992.         $g $yy intval($yy/4);
  993.         $jan1_weekday intval((((($c 10045$g7);
  994.         // weekday for year-month-day
  995.         $h $day_of_year_number ($jan1_weekday 11;
  996.         $weekday intval(($h 17);
  997.         // find if Y M D falls in YearNumber Y-1, WeekNumber 52 or
  998.         if ($day_of_year_number <= ($jan1_weekday&& $jan1_weekday 4){
  999.             $yearnumber $year 1;
  1000.             if ($jan1_weekday == || ($jan1_weekday == && $y_1_isleap)) {
  1001.                 $weeknumber 53;
  1002.             else {
  1003.                 $weeknumber 52;
  1004.             }
  1005.         else {
  1006.             $yearnumber $year;
  1007.         }
  1008.         // find if Y M D falls in YearNumber Y+1, WeekNumber 1
  1009.         if ($yearnumber == $year{
  1010.             if ($y_isleap{
  1011.                 $i 366;
  1012.             else {
  1013.                 $i 365;
  1014.             }
  1015.             if (($i $day_of_year_number($weekday)) {
  1016.                 $yearnumber++;
  1017.                 $weeknumber 1;
  1018.             }
  1019.         }
  1020.         // find if Y M D falls in YearNumber Y, WeekNumber 1 through 53
  1021.         if ($yearnumber == $year{
  1022.             $j $day_of_year_number ($weekday($jan1_weekday 1);
  1023.             //$weeknumber = intval($j / 7) + 1; // kludge!!! - JMC
  1024.                $weeknumber intval($j 7)// kludge!!! - JMC
  1025.             if ($jan1_weekday 4{
  1026.                 $weeknumber--;
  1027.             }
  1028.         }
  1029.         // put it all together
  1030.         if ($weeknumber 10)
  1031.             $weeknumber '0'.$weeknumber;
  1032.         return "{$yearnumber}-{$weeknumber}-{$weekday}";
  1033.     }
  1034.  
  1035.     /**
  1036.      * Get a list of timezones to be worked with
  1037.      */
  1038.     function get_timezone_list($use_default false{
  1039.         static $timezone_options;
  1040.  
  1041.         if (!$timezone_options{
  1042.             $timezone_options array();
  1043.  
  1044.             if ($use_default)
  1045.                 $timezone_options['default''-- Use Default Time Zone --';
  1046.  
  1047.             foreach ($GLOBALS['_DATE_TIMEZONE_DATA'as $tz_key => $tz{
  1048.                 $offset $tz['offset'];
  1049.  
  1050.                 $absoffset abs($offset /= 60000);
  1051.                 $plusminus $offset '-' '+';
  1052.                 $gmtoff sprintf("GMT%1s%02d:%02d"$plusminus$absoffset 60$absoffset (intval($absoffset 6060));
  1053.                 $tzlongshort $tz['longname'' (' $tz['shortname'')';
  1054.                 $timezone_options[$tz_keysprintf('%-28.28s: %-36.36s %s'$tz_key$tzlongshort$gmtoff);
  1055.             }
  1056.         }
  1057.  
  1058.         return $timezone_options;
  1059.     }
  1060.  
  1061.     /**
  1062.      * Per http://www.w3.org/TR/NOTE-datetime
  1063.      */
  1064.     function get_iso8601_datetime($timestamp$user false{
  1065.         return $this->strftime('%Y-%m-%dT%H:%M:%S%O'$timestamp$user);
  1066.     }
  1067.  
  1068.     function get_rfc2822_datetime($timestamp false$user false{
  1069.         if (!$timestamp)
  1070.             $timestamp time();
  1071.  
  1072.     # rfc2822 requires dates to be en formatted
  1073.         $saved_locale @setlocale(0);
  1074.         @setlocale ('en_US');
  1075.     #was return date('D, j M Y H:i:s ', $time) . $this->timezone_offset($time, 'no colon');
  1076.         $rv $this->strftime('%a, %e %b %Y %H:%M:%S'$timestamp$user)$this->get_rfc2822_timezone_offset($timestamp$user);
  1077.  
  1078.     # switch back to the 'saved' locale
  1079.         if ($saved_locale)
  1080.             @setlocale ($saved_locale);
  1081.  
  1082.         return $rv;
  1083.     }
  1084.  
  1085.     function get_rfc2822_timezone_offset($time false$no_colon false$user false{
  1086.         if ($time === false)
  1087.             $time time();
  1088.  
  1089.         $secs $this->strftime('%Z'$time$user);
  1090.  
  1091.         if ($secs 0{
  1092.             $sign '-';
  1093.  
  1094.             $secs = -$secs;
  1095.         else {
  1096.             $sign '+';
  1097.         }
  1098.  
  1099.         $colon $no_colon '' ':';
  1100.         $mins intval(($secs 3060);
  1101.  
  1102.         return sprintf("%s%02d%s%02d"$sign$mins 60$colon$mins 60);
  1103.     }
  1104.  
  1105.     function set_locale($user false{
  1106.         static $locale false;
  1107.  
  1108.         if (!$locale{
  1109.             # breaks the RFC 2822 code
  1110.             $locale @setlocale(LC_TIME$this->get_locale($user));
  1111.             #print "<pre>set_locale(): locale=$locale\n</pre>";
  1112.         }
  1113.  
  1114.         return $locale;
  1115.     }
  1116.  
  1117.     function daysInMonth$month$year {
  1118.         switch$month {
  1119.             case 1:
  1120.             case 3:
  1121.             case 5:
  1122.             case 7:
  1123.             case 8:
  1124.             case 10:
  1125.             case 12:
  1126.             case 0// == 12
  1127.                 return 31;
  1128.  
  1129.             case 4:
  1130.             case 6:
  1131.             case 9:
  1132.             case 11:
  1133.                 return 30;
  1134.  
  1135.             case 2:
  1136.                 return $this->is_leap_year$year 29 28;
  1137.  
  1138.             default:
  1139.                 assertFALSE );
  1140.         }
  1141.     }
  1142.  
  1143.     /**
  1144.     * Get a hash of holidays for a given year
  1145.     * @param $pYear the year in question
  1146.     * @param $pCountryCode -- the country in question - only US is supported currently
  1147.     * @return an associative array containing the holidays occuring in the given year they key is a date stamp of the form Y-m-d, the value is the name of the corresponding holiday
  1148.     * @access public
  1149.     ***/
  1150.     static function getHolidays$pYear=NULL$pCountryCode='US' {
  1151.         $return array();
  1152.  
  1153.         ifempty$pYear ) ) {
  1154.             $pYear date'Y' );
  1155.         }
  1156.  
  1157.         switch$pCountryCode {
  1158.             case 'UK':
  1159.                 $return[date'Y-m-d'strtotime("-1 week monday"strtotime("1 september $pYear")) 43200)'Bank Holiday';
  1160.                 break;
  1161.             case 'US':
  1162.             default:
  1163.                 // First off, the simple ones
  1164.                 $return[$pYear '-01-01''New Year`s Day';
  1165.                 //$return[$pYear . '-02-14'] = 'Valentine`s Day';
  1166.                 $return[$pYear '-06-14''Flag Day';
  1167.                 $return[$pYear '-07-04''Independence Day';
  1168.                 $return[$pYear '-11-11''Veteran`s Day';
  1169.                 $return[$pYear '-12-25''Christmas';
  1170.  
  1171.                 // Martin Luther King, Jr. Day - third Monday in January
  1172.                 $return[date'Y-m-d'strtotime'2 weeks monday'strtotime"January 1, $pYear) ) 43200 )'Martin Luther King, Jr. Day';
  1173.  
  1174.                 // Presidents` Day - third Monday in February
  1175.                 $return[date'Y-m-d'strtotime'2 weeks monday'strtotime"February 1, $pYear) ) 43200 )'Presidents` Day';
  1176.  
  1177.                 // Mardi Gras - Tuesday ~47 days before Easter
  1178.                 //$return[date( 'Y-m-d', strtotime( 'last tuesday 46 days ago', easter_date( $pYear ) ) + 43200 )] = 'Mardi Gras';
  1179.  
  1180.                 // Memorial Day - last Monday in May
  1181.                 $return[date'Y-m-d'strtotime'-1 week monday'strtotime"June 1, $pYear) ) 43200 )'Memorial Day';
  1182.  
  1183.                 // Labor Day - first Monday in September
  1184.                 $return[date'Y-m-d'strtotime'monday'strtotime"September 1, $pYear) ) 43200 )'Labor Day';
  1185.  
  1186.                 // Columbus Day - second Monday in October
  1187.                 $return[date'Y-m-d'strtotime'1 week monday'strtotime"October 1, $pYear) ) 43200 )'Columbus Day';
  1188.  
  1189.                 // Thanksgiving - fourth Thursday in November
  1190.                 $return[date'Y-m-d'strtotime'3 weeks thursday'strtotime"November 1, $pYear) ) 43200 )'Thanksgiving';
  1191.  
  1192.                 ksort$return );
  1193.                 break;
  1194.         }
  1195.  
  1196.         // Common to all
  1197.  
  1198.         // Easter - the Sunday after the first full moon which falls on or after the Spring Equinox
  1199.         // thank god PHP has a function for that...
  1200.         $return[date'Y-m-d'easter_date$pYear 43200 )'Easter';
  1201.  
  1202.         return $return;
  1203.  
  1204.     }
  1205.  
  1206.     function calculateTimeZoneDate$dateTime$fromTZ$toTZ$fromLocation 'North America'$toLocation 'GMT' {
  1207.  
  1208.         $retval     $dateTime;
  1209.         $timeStamp  strtotime$dateTime );
  1210.  
  1211.         $timeZonesArray array'GMT' => array'GMT' => +// GMT
  1212.                                                      ),
  1213.                 'North America'  =>  array'NST' => -3.5// Newfoundland Standard Time
  1214.                                             'NDT' => -2.5// Newfoundland Daylight Time
  1215.                                             'AST' => -4// Atlantic Standard Time
  1216.                                             'ADT' => -3// Atlantic Daylight Time
  1217.                                             'EST' => -5// Eastern Standard Time
  1218.                                             'EDT' => -4// Eastern Daylight Time
  1219.                                             'CST' => -6// Central Standard Time
  1220.                                             'CDT' => -5// Central Daylight Time
  1221.                                             'MST' => -7// Central Daylight Time
  1222.                                             'MDT' => -6// Mountain Daylight Time
  1223.                                             'PST' => -8// Pacific Standard Time
  1224.                                             'PDT' => -7// Pacific Daylight Time
  1225.                                             'AKST' => -9// Alaska Standard Time
  1226.                                             'AKDT' => -8// Alaska Daylight Time
  1227.                                             'HAST' => -10// Hawaii-Aleutian Standard Time
  1228.                                             'HADT' => -// Hawaii-Aleutian Daylight Time
  1229.                                             ),
  1230.                 'Australia'      =>  array'NFT' => +11.5// Norfolk (Island) Time
  1231.                                             'EST' => +10// Eastern Standard Time
  1232.                                             'EDT' => +11// Eastern Daylight Time
  1233.                                             'CST' => +9.5// Central Standard Time
  1234.                                             'CDT' => +10.5// Central Daylight Time
  1235.                                             'WST' => +8// Western Standard Time
  1236.                                             'CXT' => +7// Christmas Island Time
  1237.                                             ),
  1238.                 'Europe'         =>  array'GMT' => +0// Greenwich Mean Time
  1239.                                             'BST' => +1// British Summer Time
  1240.                                             'IST' => +1// Irish Summer Time
  1241.                                             'WET' => +0// Western European Time
  1242.                                             'WEST' => +1// Western European Summer Time
  1243.                                             'CET' => +1// Central European Time
  1244.                                             'CEST' => +2// Central European Summer Time
  1245.                                             'EET' => +2// Eastern European Time
  1246.                                             'EEST' => +// Eastern European Summer Time
  1247.                                             ),
  1248.                 'Military'       =>  array'Z' => +0// Zulu Time Zone
  1249.                                             'Y' => -12// Yankee Time Zone
  1250.                                             'X' => -11// X-ray Time Zone
  1251.                                             'W' => -10// Whiskey Time Zone
  1252.                                             'V' => -9// Victor Time Zone
  1253.                                             'U' => -8// Uniform Time Zone
  1254.                                             'T' => -7// Tango Time Zone
  1255.                                             'S' => -6// Sierra Time Zone
  1256.                                             'R' => -5// Romeo Time Zone
  1257.                                             'Q' => -4// Quebec Time Zone
  1258.                                             'P' => -3// Papa Time Zone
  1259.                                             'O' => -2// Oscar Time Zone
  1260.                                             'N' => -1// November Time Zone
  1261.                                             'A' => +1// Alpha Time Zone
  1262.                                             'B' => +2// Bravo Time Zone
  1263.                                             'C' => +3// Charlie Time Zone
  1264.                                             'D' => +4// Delta Time Zone
  1265.                                             'E' => +5// Echo Time Zone
  1266.                                             'F' => +6// Foxtrot Time Zone
  1267.                                             'G' => +7// Golf Time Zone
  1268.                                             'H' => +8// Hotel Time Zone
  1269.                                             'I' => +9// India Time Zone
  1270.                                             'K' => +10// Kilo Time Zone
  1271.                                             'L' => +11// Lima Time Zone
  1272.                                             'M' => +12 // Mike Time Zone
  1273.                                             ));
  1274.  
  1275.             $fromGMTDiff  $timeZonesArray[$fromLocation][$fromTZ];
  1276.             $toGMTDiff    $timeZonesArray[$toLocation][$toTZ];
  1277.  
  1278.             if(( '' != trim$fromGMTDiff )) && '' != trim$toGMTDiff ))) {
  1279.             if$fromGMTDiff $toGMTDiff {
  1280.                 $netDiff $fromGMTDiff $toGMTDiff;
  1281.             else {
  1282.                 $netDiff $toGMTDiff $fromGMTDiff;
  1283.             }
  1284.             $retval date'Y-m-d h:i:sa'$timeStamp 3600 $netDiff )));
  1285.  
  1286.         }
  1287.          return $retval;
  1288.  
  1289.     // end function calculateTimeZoneDate()
  1290.     
  1291. }
  1292. ?>

Documentation generated on Wed, 29 Jul 2015 13:55:47 +0000 by phpDocumentor 1.5.0-lsces