Source for file date.php

Documentation is available at date.php

  1. <?php
  2. /**
  3. * Simple date and time classes to perform basic date calculations
  4. *
  5. @author    Stuart Prescott
  6. @copyright  Copyright Stuart Prescott
  7. @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  8. @version    $Id$
  9. @package    Bumblebee
  10. @subpackage Misc
  11. */
  12.  
  13. /** Load ancillary functions */
  14. require_once 'inc/typeinfo.php';
  15.  
  16. /** config system */
  17. require_once 'inc/bb/configreader.php';
  18.  
  19. /**
  20. * Simple date class to perform basic date calculations
  21. *
  22. * WARNING USING TICKS DIRECTLY IS DANGEROUS
  23. *
  24. * The ticks variable here is a little problematic... daylight saving transitions tend
  25. * to make it rather frought. For example, for the purposes of this system,
  26. * if you want to know what 4 days after 9am 20th March
  27. * is, you expect to get 9am 23rd March regardless of a timezone change from daylight saving.
  28. *
  29. * For example, this might not give you what you want:<code>
  30. * $date = new SimpleDate('2005-03-20');
  31. * $date->addSecs(4*24*60*60);   // add 4 days
  32. * </code>
  33. * But this will:<code>
  34. * $date = new SimpleDate('2005-03-20');
  35. * $date->addDays(4);   // add 4 days
  36. * </code>
  37. *
  38. @package    Bumblebee
  39. @subpackage Misc
  40. */
  41. class SimpleDate {
  42.   /**
  43.   * cache of date in string format
  44.   * @var string 
  45.   */
  46.   var $_cache = array();
  47.   /**
  48.   * date in seconds since epoch
  49.   * @var integer 
  50.   */
  51.   var $ticks  = '';
  52.   /**
  53.   * is a valid date-time
  54.   * @var boolean 
  55.   */
  56.   var $isValid = 1;
  57.  
  58.   /**
  59.   * construct a Date-Time object
  60.   *
  61.   * constructor will work with $time in the following formats:
  62.   * - YYYY-MM-DD            (assumes 00:00:00 for time part)
  63.   * - YYYY-MM-DD HH:MM      (assumes :00 for seconds part)
  64.   * - YYYY-MM-DD HH:MM:SS
  65.   * - seconds since epoch
  66.   * - SimpleDate object
  67.   * @param mixed $time  initial time to use
  68.   */
  69.   function SimpleDate($time{
  70.     ($time == NULL&& $time 0;
  71.     if (is_numeric($time)) {
  72.       $this->setTicks($time);
  73.     elseif (type_is_a($time'SimpleDate')) {
  74.       $this->setTicks($time->ticks);
  75.     else {
  76.       $this->setStr($time);
  77.     }
  78.   }
  79.  
  80.   /**
  81.   * set the date and time from a string
  82.   *
  83.   * - YYYY-MM-DD            (assumes 00:00:00)
  84.   * - YYYY-MM-DD HH:MM      (assumes :00)
  85.   * - YYYY-MM-DD HH:MM:SS
  86.   * @param mixed $s date time string
  87.   */
  88.   function setStr($s{
  89.     $this->isValid = 1;
  90.     $this->_setTicks($s);
  91.   }
  92.  
  93.   function dateTimeString({
  94.     if (isset($this->_cache['datetime'])) {
  95.       $this->_cache['datetime'strftime('%Y-%m-%d %H:%M:%S'$this->ticks);
  96.     }
  97.     return $this->_cache['datetime'];
  98.   }
  99.  
  100.   function timeString({
  101.     if (isset($this->_cache['time'])) {
  102.       $this->_cache['time'strftime('%H:%M:%S'$this->ticks);
  103.     }
  104.     return $this->_cache['time'];
  105.   }
  106.  
  107.   function dateString({
  108.     if (isset($this->_cache['date'])) {
  109.       $this->_cache['date'strftime('%Y-%m-%d'$this->ticks);
  110.     }
  111.     return $this->_cache['date'];
  112.   }
  113.  
  114.   /**
  115.   * get a short string representation for the current locale
  116.   *
  117.   * @return string time value in short time format
  118.   */
  119.   function getShortDateString({
  120.     if (isset($this->_cache['lshortDate'])) {
  121.       $conf ConfigReader::getInstance();
  122.       $format $conf->value('language''date_shortdate''Y-m-d');
  123.       $this->_cache['lshortDate'$this->getStringByFormat($format);
  124.     }
  125.     return $this->_cache['lshortDate'];
  126.   }
  127.  
  128.   /**
  129.   * get a short string representation for the current locale
  130.   *
  131.   * @return string time value in short time format
  132.   */
  133.   function getShortTimeString({
  134.     if (isset($this->_cache['lshortTime'])) {
  135.       $conf ConfigReader::getInstance();
  136.       $format $conf->value('language''date_shorttime''H:i');
  137.       $this->_cache['lshortTime'$this->getStringByFormat($format);
  138.     }
  139.     return $this->_cache['lshortTime'];
  140.   }
  141.  
  142.   /**
  143.   * get a short string representation for the current locale
  144.   *
  145.   * @return string time value in short time format
  146.   */
  147.   function getShortDateTimeString({
  148.     if (isset($this->_cache['lshortDateTime'])) {
  149.       $conf ConfigReader::getInstance();
  150.       $format $conf->value('language''date_shortdatetime''Y-m-d H:i');
  151.       $this->_cache['lshortDateTime'$this->getStringByFormat($format);
  152.     }
  153.     return $this->_cache['lshortDateTime'];
  154.   }
  155.  
  156.   /**
  157.   * get a long string representation for the current locale
  158.   *
  159.   * @return string time value in long time format
  160.   */
  161.   function getLongDateString({
  162.     if (isset($this->_cache['llongDate'])) {
  163.       $conf ConfigReader::getInstance();
  164.       $format $conf->value('language''date_longdate''D F j, Y');
  165.       $this->_cache['llongDate'$this->getStringByFormat($format);
  166.     }
  167.     return $this->_cache['llongDate'];
  168.   }
  169.  
  170.   /**
  171.   * get a long string representation for the current locale
  172.   *
  173.   * @return string time value in long time format
  174.   */
  175.   function getLongTimeString({
  176.     if (isset($this->_cache['llongTime'])) {
  177.       $conf ConfigReader::getInstance();
  178.       $format $conf->value('language''date_longtime''H:i:s');
  179.       $this->_cache['llongTime'$this->getStringByFormat($format);
  180.     }
  181.     return $this->_cache['llongTime'];
  182.   }
  183.  
  184.   /**
  185.   * get a long string representation for the current locale
  186.   *
  187.   * @return string time value in long time format
  188.   */
  189.   function getLongDateTimeString({
  190.     if (isset($this->_cache['llongDateTime'])) {
  191.       $conf ConfigReader::getInstance();
  192.       $format $conf->value('language''date_longdatetime''H:i:s, D F j, Y');
  193.       $this->_cache['llongDateTime'$this->getStringByFormat($format);
  194.     }
  195.     return $this->_cache['llongDateTime'];
  196.   }
  197.  
  198.   /**
  199.   * Get a string representation of this time in the specified format
  200.   *
  201.   * Recognised format characters are as follows:
  202.   *
  203.   * d    Day of the month, 2 digits with leading zeros    01 to 31
  204.   * D    A textual representation of a day, three letters    Mon through Sun
  205.   * j    Day of the month without leading zeros    1 to 31
  206.   * l (lowercase 'L')    A full textual representation of the day of the week    Sunday through Saturday
  207.   *
  208.   * F    A full textual representation of a month, such as January or March    January through December
  209.   * m    Numeric representation of a month, with leading zeros    01 through 12
  210.   * M    A short textual representation of a month, three letters    Jan through Dec
  211.   * n    Numeric representation of a month, without leading zeros    1 through 12
  212.   *
  213.   * Y    A full numeric representation of a year, 4 digits    Examples: 1999 or 2003
  214.   * y    A two digit representation of a year    Examples: 99 or 03
  215.   *
  216.   * a    Lowercase Ante meridiem and Post meridiem    am or pm
  217.   * A    Uppercase Ante meridiem and Post meridiem    AM or PM
  218.   * g    12-hour format of an hour without leading zeros    1 through 12
  219.   * G    24-hour format of an hour without leading zeros    0 through 23
  220.   * h    12-hour format of an hour with leading zeros    01 through 12
  221.   * H    24-hour format of an hour with leading zeros    00 through 23
  222.   * i    Minutes with leading zeros    00 to 59
  223.   * s    Seconds, with leading zeros    00 through 59
  224.   *
  225.   * @return string time value in short time format
  226.   */
  227.   function getStringByFormat($format{
  228.     static $i18n null;
  229.     if ($i18n === null{
  230.       $i18n date_make_translation_array();
  231.     }
  232.     $s '';  // return string
  233.         $c '';  // current character
  234.         $p '';  // previous character
  235.  
  236.     #print "Analysing $format";
  237.         $formatLen strlen($format);
  238.     for ($i=0$i<$formatLen$i++{
  239.       $c $format[$i];
  240.       if ($i && $format[$i-1== '\\'{
  241.         $s .= $c;
  242.         next;
  243.       }
  244.       #print " $i: $c ($s)...";
  245.  
  246.       switch ($c{
  247.         // day
  248.         case 'd':
  249.         case 'j':
  250.         // month
  251.         case 'm':
  252.         case 'n':
  253.         // year
  254.         case 'y':
  255.         case 'Y':
  256.         // time
  257.         case 'g':
  258.         case 'G':
  259.         case 'h':
  260.         case 'H':
  261.         case 'i':
  262.         case 's':
  263.           $s .= date($c$this->ticks);
  264.           break;
  265.  
  266.         // day
  267.         case 'D':
  268.         case 'l':
  269.         // month
  270.         case 'F':
  271.         case 'M':
  272.         // time
  273.         case 'a':
  274.         case 'A':
  275.           $s .= $i18n[date($c$this->ticks)];
  276.           #$s .= date($c, $this->ticks);
  277.           break;
  278.  
  279.         case '\\':
  280.           break;
  281.         default:
  282.           $s .= $c;
  283.           break;
  284.       }
  285.     }
  286.     return $s;
  287.   }
  288.  
  289.   /**
  290.   * set the date and time from seconds since epoch
  291.   *
  292.   * @param mixed $t ticks
  293.   */
  294.   function setTicks($t{
  295.     $this->isValid = 1;
  296.     $this->ticks = $t;
  297.     $this->_cache = array();
  298.     //$this->_setStr();
  299.   }
  300.  
  301.   function _setTicks($s{
  302.     #echo "SimpleDate::Ticks $s<br />";
  303.     #preDump(debug_backtrace());
  304.     $this->ticks = strtotime($s);
  305.     $this->_cache = array();
  306.     $this->isValid = $this->isValid && ($this->ticks != '' && $this->ticks != -1);
  307.   }
  308.  
  309.   /**
  310.   * add a whole number of days to the current date-time
  311.   * @param integer $d days to add
  312.   */
  313.   function addDays($d{
  314.     $this->addTimeParts(0,0,0,$d,0,0);
  315.   }
  316.  
  317.   /**
  318.   * add a time (i.e. a number of seconds) to the current date-time
  319.   *
  320.   * - SimpleTime object
  321.   * - seconds
  322.   * @param mixed $d days to add
  323.   */
  324.   function addTime($t{
  325.     if (type_is_a($t'SimpleTime')) {
  326.       $this->ticks += $t->seconds();
  327.     else {
  328.       $this->ticks += $t;
  329.     }
  330.     $this->_cache = array();
  331.   }
  332.  
  333.   /**
  334.   * add a whole number of seconds to the current date-time
  335.   * @param integer $s seconds to add
  336.   */
  337.   function addSecs($s{
  338.     $this->ticks += $s;
  339.     $this->_cache = array();
  340.   }
  341.  
  342.   /**
  343.   * round (down) the date-time to the current day
  344.   *
  345.   * sets the current YYY-MM-DD HH:MM:SS to YYYY-MM-DD 00:00:00
  346.   */
  347.   function dayRound({
  348.     // this might look as though it would be faster by avoiding the expensive strtotime() call,
  349.     // (10000 reps took average 0.490s with PHP 4.4.2, libc6-2.3.6)
  350.     //    $this->setTimeParts(0,0,0,date('d', $this->ticks),date('m', $this->ticks),date('Y', $this->ticks));
  351.     // but this is actually faster.
  352.     // (10000 reps took average 0.385s with PHP 4.4.2, libc6-2.3.6; that's 21% faster)
  353.     $this->setStr($this->dateString());
  354.   }
  355.  
  356.   /**
  357.   * round (down) the date-time to the start of the current week (Sunday)
  358.   */
  359.   function weekRound({
  360.     $this->dayRound();
  361.     $this->addDays(-$this->dow());
  362.   }
  363.  
  364.   /**
  365.   * round (down) the date-time to the start of the current month (the 1st)
  366.   */
  367.   function monthRound({
  368.     $this->dayRound();
  369.     $this->addDays(-1*$this->dom()+1);
  370.   }
  371.  
  372.   /**
  373.   * round (down) the date-time to the start of the current quarter (1st Jan, 1st Apr, 1st Jul, 1st Oct)
  374.   */
  375.   function quarterRound({
  376.     $month $this->moy();
  377.     $quarter floor(($month-1)/3)*3+1;
  378.     $this->setTimeParts(0,0,0,1,$quarter,$this->year());
  379.   }
  380.  
  381.   /**
  382.   * round (down) the date-time to the start of the current year (1st Jan)
  383.   */
  384.   function yearRound({
  385.     $this->dayRound();
  386.     $this->addDays(-1*$this->doy());
  387.   }
  388.  
  389.   /**
  390.   * returns the number of days between two dates ($this - $date)
  391.   * note that it will return fractional days across daylight saving boundaries
  392.   * @param SimpleDate $date date to subtract from this date
  393.   */
  394.   function daysBetween($date{
  395.     return $this->subtract($date(24 60 60);
  396.   }
  397.  
  398.   /**
  399.   * returns the number of days between two dates ($this - $date) accounting for daylight saving
  400.   * @param SimpleDate $date date to subtract from this date
  401.   */
  402.   function dsDaysBetween($date{
  403.     //Calculate the number of days as a fraction, removing fractions due to daylight saving
  404.     $numdays $this->daysBetween($date);
  405.  
  406.     //We don't want to count an extra day (or part thereof) just because the day range
  407.     //includes going from summertime to wintertime so the date range includes an extra hour!
  408.  
  409.     $tz1 date('Z'$this->ticks);
  410.     $tz2 date('Z'$date->ticks);
  411.     if ($tz1 == $tz2{
  412.       // same timezone, so return the computed amount
  413.       #echo "Using numdays $tz1 $tz2 ";
  414.       return $numdays;
  415.     else {
  416.       // subtract the difference in the timezones to fix this
  417.       #echo "Using tzinfo: $tz1 $tz2 ";
  418.       return $numdays ($tz2-$tz1(24*60*60);
  419.     }
  420.   }
  421.  
  422.   /**
  423.   * returns the number of days (or part thereof) between two dates ($this - $d)
  424.   * @param SimpleDate $date date to subtract from this date
  425.   */
  426.   function partDaysBetween($date{
  427.     //we want this to be an integer and since we want "part thereof" we'd normally round up
  428.     //but daylight saving might cause problems....  We also have to include the part day at
  429.     //the beginning and the end
  430.  
  431.     $startwhole $date;
  432.     $startwhole->dayRound();
  433.     $stopwhole $this;
  434.     $stopwhole->ticks += 24*60*60-1;
  435. //     $stopwhole->_setStr();
  436.     $stopwhole->dayRound();
  437.  
  438.     return $stopwhole->dsDaysBetween($startwhole);
  439.   }
  440.  
  441.   /**
  442.   * returns the number of seconds between two times
  443.   * NB this does not specially account for daylight saving changes, so will not always give
  444.   * the 24*60*60 for two datetimes that are 1 day apart on the calendar...!
  445.   * @param SimpleDate $date date to subtract from this date
  446.   */
  447.   function subtract($date{
  448.     #echo "$this->ticks - $date->ticks ";
  449.     return $this->ticks - $date->ticks;
  450.   }
  451.  
  452.   /**
  453.   * returns a SimpleTime object for just the time component of this date time
  454.   *
  455.   * @return SimpleTime object of just the HH:MM:SS component of this date
  456.   */
  457.   function timePart({
  458.     $timestring strftime('%H:%M:%S'$this->ticks);
  459.     return new SimpleTime($timestring);
  460.   }
  461.  
  462.   /**
  463.   * Sets the time component of this date-time to the specified time but with the same date as currently set
  464.   *
  465.   * The specified time can be HH:MM HH:MM:SS, seconds since midnight or a SimpleTime object
  466.   * @param mixed time to use
  467.   */
  468.   function setTime($s{
  469.     //echo $this->dump().$s.'<br/>';
  470.  
  471.     // Benchmarks of 10000 calls to setTime($time)
  472.     //
  473.     // Original algorithm, dayRound() and then addTimeParts(); avg over 10 benchmark runs = 1.28s
  474.     // $this->dayRound();
  475.     // $time = new SimpleTime($s);
  476.     // $this->addTimeParts($time->part('s'), $time->part('i'), $time->part('H'), 0,0,0);
  477.  
  478.     // setTimeParts() directly; avg over 10 benchmark runs = 0.80s
  479.     $time new SimpleTime($s);
  480.     //$this->setTimeParts(date('s', $time->ticks),date('i', $time->ticks),date('H', $time->ticks),
  481.     //                    date('d', $this->ticks),date('m', $this->ticks),date('Y', $this->ticks));
  482.     $this->setTimeParts($time->part('s'),        $time->part('i'),        $time->part('H'),
  483.                         date('d'$this->ticks)date('m'$this->ticks)date('Y'$this->ticks));
  484.  
  485.     return $this;
  486.   }
  487.  
  488.  
  489.   /**
  490.   * Sets this SimpleDate to the earlier of $this and $t
  491.   *
  492.   * @param SimpleDate $t 
  493.   */
  494.   function min($t{
  495.     $this->setTicks(min($t->ticks$this->ticks));
  496.   }
  497.  
  498.   /**
  499.   * Sets this SimpleDate to the later of $this and $t
  500.   *
  501.   * @param SimpleDate $t 
  502.   */
  503.   function max($t{
  504.     $this->setTicks(max($t->ticks$this->ticks));
  505.   }
  506.  
  507.   /**
  508.   * round time down to the nearest $g time-granularity measure
  509.   *
  510.   * Example: if this date time is set to 2005-11-21 17:48 and
  511.   * $g represents 00:15:00 (i.e. 15 minutes) then this date-time would
  512.   * be set to 2005-11-21 17:45 by rounding to the nearest 15 minutes.
  513.   *
  514.   * @param SimpleTime $g 
  515.   */
  516.   function floorTime($g{
  517.     $tp $this->timePart();
  518.     $tp->floorTime($g);
  519.     $this->setTime($tp->timeString());
  520.   }
  521.  
  522.   /**
  523.   * Add components to the current date-time
  524.   *
  525.   * Note that this function will take account of daylight saving in unusual (but quite sensible)
  526.   * ways... for example, if $today is a SimpleDate object representing midday the day before
  527.   * daylight saving ends, then $today->addTimeParts(24*60*60) will give a different result
  528.   * to $today->addTimeParts(0,0,0,1). The former will be exactly 24 hours later than the original
  529.   * value of $today (11:00), but the latter will 1 calendar day later (12:00).
  530.   *
  531.   * @param integer $sec  (optional) number of seconds to add to this date-time
  532.   * @param integer $min  (optional) number of minutes to add to this date-time
  533.   * @param integer $hour (optional) number of hours to add to this date-time
  534.   * @param integer $day  (optional) number of days to add to this date-time
  535.   * @param integer $month  (optional) number of months to add to this date-time
  536.   * @param integer $year  (optional) number of years to add to this date-time
  537.   */
  538.   function addTimeParts($sec=0$min=0$hour=0$day=0$month=0$year=0{
  539.     $this->ticks = mktime(
  540.                             date('H',$this->ticks$hour,
  541.                             date('i',$this->ticks$min,
  542.                             date('s',$this->ticks$sec,
  543.                             date('m',$this->ticks$month,
  544.                             date('d',$this->ticks$day,
  545.                             date('y',$this->ticks$year
  546.                         );
  547.     $this->_cache = array();
  548.   }
  549.  
  550.   /**
  551.   * Set current date-time by components
  552.   *
  553.   * @param integer $sec  (optional) seconds to set
  554.   * @param integer $min  (optional) minutes to set
  555.   * @param integer $hour (optional) hours to add set
  556.   * @param integer $day  (optional) days to add set
  557.   * @param integer $month  (optional) months to set
  558.   * @param integer $year  (optional) years to set
  559.   */
  560.   function setTimeParts($sec=0$min=0$hour=0$day=0$month=0$year=0{
  561.     $this->ticks = mktime(
  562.                             $hour,
  563.                             $min,
  564.                             $sec,
  565.                             $month,
  566.                             $day,
  567.                             $year
  568.                         );
  569.     $this->_cache = array();
  570.   }
  571.  
  572.   /**
  573.   * return the day of week of the current date.
  574.   * @return integer day of week (0 == Sunday, 6 == Saturday)
  575.   */
  576.   function dow({
  577.     return date('w'$this->ticks);
  578.   }
  579.  
  580.   /**
  581.   * return the day of week of the current date as a string (in current language)
  582.   * @return string day of week (Sunday, Monday, etc)
  583.   */
  584.   function dowStr({
  585.     return $this->_T_(date('l'$this->ticks));
  586.   }
  587.  
  588.   /**
  589.   * return the (short) day of week of the current date as a string (in current language)
  590.   * @return string day of week (Sun, Mon, etc)
  591.   */
  592.   function dowShortStr({
  593.     return $this->_T_(date('D'$this->ticks));
  594.   }
  595.  
  596.   /**
  597.   * return the day of month
  598.   * @return integer day of month (1..31)
  599.   */
  600.   function dom({
  601.     return intval(date('d'$this->ticks));  // use intval to remove the leading zero
  602.   }
  603.  
  604.   /**
  605.   * return integer month of year (1..12)
  606.   * @return integer month of year (1..12)
  607.   */
  608.   function moy({
  609.     return date('m'$this->ticks);
  610.   }
  611.  
  612.   /**
  613.   * return the month of year of the current date as a string (in current language)
  614.   * @return string month of the year (January, February etc)
  615.   */
  616.   function moyStr({
  617.     return $this->_T_(date('F'$this->ticks));
  618.   }
  619.  
  620.   /**
  621.   * return the (short) month of the year of the current date as a string (in current language)
  622.   * @return string month of the year (Jan, Feb etc)
  623.   */
  624.   function moyShortStr({
  625.     return $this->_T_(date('M'$this->ticks));
  626.   }
  627.  
  628.   /**
  629.   * day of year (0..365)
  630.   * returns 365 only in leap years
  631.   * @return integer day of year (0..365)
  632.   */
  633.   function doy({
  634.     return date('z'$this->ticks);
  635.   }
  636.  
  637.   /**
  638.   * four-digit year (YYYY)
  639.   * @return integer year (e.g. 2005)
  640.   */
  641.   function year({
  642.     return date('Y'$this->ticks);
  643.   }
  644.  
  645.   /**
  646.   * dump the datetimestring and ticks in a readable format
  647.   * @param boolean $html (optional) use html line endings
  648.   * @return string datetimestring and ticks
  649.   */
  650.   function dump($html=1{
  651.     $s 'ticks = ' $this->ticks . ', ' $this->dateTimeString();
  652.     $s .= ($html '<br />' ''"\n";
  653.     return $s;
  654.   }
  655.  
  656.   /**
  657.   * translate an individual date-related word (day of week, month of year)
  658.   *
  659.   * @param string   $word    word to translate
  660.   * @returns string          translated word
  661.   */
  662.   function _T_($word{
  663.     $i18n date_make_translation_array();
  664.     return $i18n[$word];
  665.   }
  666.  
  667. // class SimpleDate
  668.  
  669.  
  670. /**
  671. * Simple time class to perform basic time calculations
  672. *
  673. @package    Bumblebee
  674. @subpackage Misc
  675. */
  676. class SimpleTime {
  677.   /**
  678.   * cache of string formatted data
  679.   * @var array 
  680.   */
  681.   var $_cache = array();
  682.   /**
  683.   * current time in integer seconds since midnight
  684.   * @var integer 
  685.   */
  686.   var $ticks = '';
  687.   /**
  688.   * is set to a valid value
  689.   * @var boolean 
  690.   */
  691.   var $isValid = 1;
  692.  
  693.   /**
  694.   * Constructor for class
  695.   *
  696.   * Accepts the following for the initial time:
  697.   * - HH:MM:SS
  698.   * - HH:MM  (assumes :00 for seconds part)
  699.   * - SimpleTime object
  700.   */
  701.   function SimpleTime($time{
  702.     #echo "New SimpleTime: $time, $type<br />";
  703.     if (is_numeric($time)) {
  704.       $this->setTicks($time);
  705.     elseif (type_is_a($time'SimpleTime')) {
  706.       $this->setTicks($time->ticks);
  707.     else {
  708.       $this->setStr($time);
  709.     }
  710.   }
  711.  
  712.   /**
  713.   * Set time by a string
  714.   */
  715.   function setStr($s{
  716.     $this->_setTicks($s);
  717.     //$this->_setStr();
  718.   }
  719.  
  720.   function timeString({
  721.     if (isset($this->_cache['time'])) {
  722.       $this->_cache['time'sprintf('%02d:%02d'$this->ticks/3600($this->ticks%3600)/60);;
  723.     }
  724.     return $this->_cache['time'];
  725.   }
  726.  
  727.   /**
  728.   * Set time by seconds since midnight
  729.   */
  730.   function setTicks($t{
  731.     $this->ticks = $t;
  732.     $this->_cache = array();
  733.   }
  734.  
  735.   function _setTicks($s{
  736.     if (preg_match('/^(\d\d):(\d\d):(\d\d)$/'$s$t)) {
  737.       #preDump($t);
  738.       $this->ticks = $t[1]*3600+$t[2]*60+$t[3];
  739.     elseif (preg_match('/^(\d\d):(\d\d)$/'$s$t|| preg_match('/^(\d):(\d\d)$/'$s$t)) {
  740.       #preDump($t);
  741.       $this->ticks = $t[1]*3600+$t[2]*60;
  742.     else {
  743.       $this->ticks = 0;
  744.       $this->inValid 0;
  745.     }
  746.     $this->_cache = array();
  747.   }
  748.  
  749.   /**
  750.   * subtract seconds $this -  $other
  751.   * @param SimpleTime $other 
  752.   * @return integer seconds difference
  753.   */
  754.   function subtract($other{
  755.     return $this->ticks - $other->ticks;
  756.   }
  757.  
  758.   /**
  759.   * add seconds to this time
  760.   * @param integer $s 
  761.   */
  762.   function addSecs($s{
  763.     $this->ticks += $s;
  764.     $this->_cache = array();
  765.   }
  766.  
  767.   /**
  768.   * return current seconds
  769.   * @return integer current seconds since midnight
  770.   */
  771.   function seconds({
  772.     return $this->ticks;
  773.   }
  774.  
  775.   /**
  776.   * set this value to the earlier of $this and $other
  777.   * @param SimpleTime $other 
  778.   */
  779.   function min($other{
  780.     $this->setTicks(min($other->ticks$this->ticks));
  781.   }
  782.  
  783.   /**
  784.   * set this value to the later of $this and $other
  785.   * @param SimpleTime $other 
  786.   */
  787.   function max($t{
  788.     $this->setTicks(max($t->ticks$this->ticks));
  789.   }
  790.  
  791.   /**
  792.   * get a string representation that includes the number of seconds
  793.   * @return string time value in HH:MM:SS format
  794.   */
  795.   function getHMSstring({
  796.     return sprintf('%02d:%02d:%02d'$this->ticks/3600($this->ticks%3600)/60$this->ticks%60);
  797.   }
  798.  
  799.   /**
  800.   * get a short string representation for the current locale
  801.   *
  802.   * @return string time value in short time format
  803.   */
  804.   function getShortString({
  805.     if (isset($this->_cache['short'])) {
  806.       $conf ConfigReader::getInstance();
  807.       $format $conf->value('language''date_shorttime''H:i');
  808.       $this->_cache['short'$this->getStringByFormat($format);
  809.     }
  810.     return $this->_cache['short'];
  811.   }
  812.  
  813.   /**
  814.   * get a long string representation for the current locale
  815.   *
  816.   * @return string time value in long time format
  817.   */
  818.   function getLongString({
  819.     if (isset($this->_cache['long'])) {
  820.       $conf ConfigReader::getInstance();
  821.       $format $conf->value('language''date_longtime''H:i:s');
  822.       $this->_cache['long'$this->getStringByFormat($format);
  823.     }
  824.     return $this->_cache['long'];
  825.   }
  826.  
  827.   /**
  828.   * Get a string representation of this time in the specified format
  829.   *
  830.   * Recognised format characters are as follows:
  831.   *
  832.   * a    Lowercase Ante meridiem and Post meridiem    am or pm
  833.   * A    Uppercase Ante meridiem and Post meridiem    AM or PM
  834.   * g    12-hour format of an hour without leading zeros    1 through 12
  835.   * G    24-hour format of an hour without leading zeros    0 through 23
  836.   * h    12-hour format of an hour with leading zeros    01 through 12
  837.   * H    24-hour format of an hour with leading zeros    00 through 23
  838.   * i    Minutes with leading zeros    00 to 59
  839.   * s    Seconds, with leading zeros    00 through 59
  840.   *
  841.   * @return string time value in short time format
  842.   */
  843.   function getStringByFormat($format{
  844.     // cache the AM/PM data to reduce time spent in i18n function
  845.     static $i18n null;
  846.     if ($i18n === null{
  847.       $i18n array();
  848.       $i18n['am'T_('am');
  849.       $i18n['AM'T_('AM');
  850.       $i18n['pm'T_('pm');
  851.       $i18n['PM'T_('PM');
  852.     }
  853.  
  854.     $s '';  // return string
  855.         $c '';  // current character
  856.         $p '';  // previous character
  857.  
  858.     #print "Analysing $format";
  859.         $formatLen strlen($format);
  860.     for ($i=0$i<$formatLen$i++{
  861.       $c $format[$i];
  862.       if ($i && $format[$i-1== '\\'{
  863.         $s .= $c;
  864.         next;
  865.       }
  866.       #print " $i: $c ($s)...";
  867.  
  868.       switch ($c{
  869.         case 'a':
  870.           $s .= $i18n[$this->part('a')];
  871.           break;
  872.         case 'A':
  873.           $s .= $i18n[$this->part('A')];
  874.           break;
  875.         case 'g':
  876.           $s .= ($this->part('h')-112 1;
  877.           break;
  878.         case 'G':
  879.           $s .= $this->part('h');
  880.           break;
  881.         case 'h':
  882.           $s .= sprintf('%02d'($this->part('h')-112 1);
  883.           break;
  884.         case 'H':
  885.           $s .= sprintf('%02d'$this->part('h'));
  886.           break;
  887.         case 'i':
  888.           $s .= sprintf('%02d'$this->part('i'));
  889.           break;
  890.         case 's':
  891.           $s .= sprintf('%02d'$this->part('s'));
  892.           break;
  893.         case '\\':
  894.           break;
  895.         default:
  896.           $s .= $c;
  897.           break;
  898.       }
  899.       #print " $s<br />";
  900.     }
  901.     return $s;
  902.   }
  903.  
  904.   /**
  905.   * round time down to the nearest $g time-granularity measure
  906.   *
  907.   * @see SimpleDate::floorTime()
  908. timestring = '';
  909. //     $this->_setStr();  * @param SimpleTime $g time granularity
  910.   */
  911.   function floorTime($g{
  912.     $gt $g->seconds();
  913.     $this->setTicks(floor(($this->ticks+1)/$gt)*$gt);
  914.   }
  915.  
  916.   /**
  917.   * round time up to the nearest $g time-granularity measure
  918.   *
  919.   * @see SimpleTime::floorTime()
  920.   * @param SimpleTime $g time granularity
  921.   */
  922.   function ceilTime($g{
  923.     $gt $g->seconds();
  924.     $this->setTicks(ceil(($this->ticks-1)/$gt)*$gt);
  925.   }
  926.  
  927.   /**
  928.   * Obtain hour, minute or seconds parts of the time
  929.   *
  930.   * return hour, minute or seconds parts of the time, emulating the date('H', $ticks) etc
  931.   * functions, but not using them as they get too badly confused with timezones to be useful
  932.   * in many situations
  933.   *
  934.   * @param char $s time part to obtain (valid parts: h, i, s for hours, mins, secs)
  935.   * @return integer part of the time
  936.   */
  937.   function part($s{
  938.     switch ($s{
  939.       //we don't actually care about zero padding in this case.
  940.       case 'H':
  941.       case 'h':
  942.         return floor($this->ticks/(3600));
  943.       //let's just allow 'm' to give minutes as well, as it's easier
  944.       case 'i':
  945.       case 'm':
  946.         return floor(($this->ticks%360060);
  947.       case 's':
  948.         return floor($this->ticks % 60);
  949.       case 'a':
  950.         return ($this->ticks % 86400 43200'am' 'pm';
  951.       case 'A':
  952.         return ($this->ticks % 86400 43200'AM' 'PM';
  953.     }
  954.     //we can't use this as we're not actually using the underlying date-time types here.
  955.     //return date($s, $this->ticks);
  956.   }
  957.  
  958.   /**
  959.   * Add another time to this time
  960.   *
  961.   * @param SimpleTime $t time to add to this one
  962.   */
  963.   function addTime($t{
  964.     $this->ticks += $t->ticks;
  965.     $this->_cache = array();
  966.   }
  967.  
  968.   /**
  969.   * dump the timestring and ticks in a readable format
  970.   * @param boolean $html (optional) use html line endings
  971.   * @return string timestring and ticks
  972.   */
  973.   function dump($html=1{
  974.     $s 'ticks = ' $this->ticks . ', ' $this->timeString();
  975.     $s .= ($html '<br />' ''"\n";
  976.     return $s;
  977.   }
  978. // class SimpleTime
  979.  
  980.  
  981. // We need to define these just so that the date formatting routines can always
  982. // return English names for the days and dates and the translation layer will
  983. // provide the correct translation. We can't just use setlocale() and strftime()
  984. // to do this because they only work if the locale is installed on the server and
  985. // this is frequently not the case (which is why we are using gettext emulation
  986. // to begin with!)
  987.   static $i18n null;
  988.  
  989.   if ($i18n !== nullreturn $i18n;
  990.  
  991.   $i18n array();
  992.   $i18n['Monday']    T_('Monday');
  993.   $i18n['Mon']       T_('Mon');
  994.   $i18n['Tuesday']   T_('Tuesday');
  995.   $i18n['Tue']       T_('Tue');
  996.   $i18n['Tues']      T_('Tue');
  997.   $i18n['Wednesday'T_('Wednesday');
  998.   $i18n['Wed']       T_('Wed');
  999.   $i18n['Thursday']  T_('Thursday');
  1000.   $i18n['Thu']       T_('Thu');
  1001.   $i18n['Thurs']     T_('Thu');
  1002.   $i18n['Friday']    T_('Friday');
  1003.   $i18n['Fri']       T_('Fri');
  1004.   $i18n['Saturday']  T_('Saturday');
  1005.   $i18n['Sat']       T_('Sat');
  1006.   $i18n['Sunday']    T_('Sunday');
  1007.   $i18n['Sun']       T_('Sun');
  1008.  
  1009.   $i18n['January']   T_('January');
  1010.   $i18n['Jan']       T_('Jan');
  1011.   $i18n['February']  T_('February');
  1012.   $i18n['Feb']       T_('Feb');
  1013.   $i18n['March']     T_('March');
  1014.   $i18n['Mar']       T_('Mar');
  1015.   $i18n['April']     T_('April');
  1016.   $i18n['Apr']       T_('Apr');
  1017.   $i18n['May']       T_('May');
  1018.   $i18n['June']      T_('June');
  1019.   $i18n['Jun']       T_('Jun');
  1020.   $i18n['July']      T_('July');
  1021.   $i18n['Jul']       T_('Jul');
  1022.   $i18n['August']    T_('August');
  1023.   $i18n['Aug']       T_('Aug');
  1024.   $i18n['September'T_('September');
  1025.   $i18n['Sep']       T_('Sep');
  1026.   $i18n['October']   T_('October');
  1027.   $i18n['Oct']       T_('Oct');
  1028.   $i18n['November']  T_('November');
  1029.   $i18n['Nov']       T_('Nov');
  1030.   $i18n['December']  T_('December');
  1031.   $i18n['Dec']       T_('Dec');
  1032.  
  1033.   $i18n['am'T_('am');
  1034.   $i18n['AM'T_('AM');
  1035.   $i18n['pm'T_('pm');
  1036.   $i18n['PM'T_('PM');
  1037.  
  1038.   return $i18n;
  1039. }
  1040.  
  1041. ?>

Documentation generated on Tue, 06 Mar 2007 10:01:12 +0000 by phpDocumentor 1.3.0