Source for file jDateTime.class.php

Documentation is available at jDateTime.class.php

  1. <?php
  2. /**
  3. @package     jelix
  4. @subpackage  utils
  5. @author      GĂ©rald Croes, Laurent Jouanneau
  6. @contributor Laurent Jouanneau, Julien Issler
  7. @contributor Loic Mathaud
  8. @contributor Florian Hatat
  9. @contributor Emmanuel Hesry, Brice G.
  10. @contributor Hadrien Lanneau <hadrien@over-blog.com>
  11. @copyright   2005-2011 Laurent Jouanneau
  12. @copyright   2007 Loic Mathaud
  13. @copyright   2007-2008 Florian Hatat
  14. @copyright   2001-2005 CopixTeam, GeraldCroes, Laurent Jouanneau
  15. @copyright   2008-2011 Julien Issler
  16. @copyright   2009 Emmanuel Hesry
  17. @copyright   2010 Hadrien Lanneau, 2011 Brice G.
  18. *
  19. *  This class was get originally from the Copix project (CopixDate.lib.php, Copix 2.3dev20050901, http://www.copix.org)
  20. *  Only few lines of code are still copyrighted 2001-2005 CopixTeam (LGPL licence).
  21. *  Initial authors of this Copix classes are Gerald Croes and Laurent Jouanneau,
  22. *  and this class was adapted/improved for Jelix by Laurent Jouanneau
  23. *
  24. @link        http://www.jelix.org
  25. @licence     http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public Licence, see LICENCE file
  26. */
  27.  
  28. /**
  29.  * Utility to manipulate dates and convert date format
  30.  * @package     jelix
  31.  * @subpackage  utils
  32.  */
  33. class jDateTime {
  34.     public $day;
  35.     public $month;
  36.     public $year;
  37.     public $hour;
  38.     public $minute;
  39.     public $second;
  40.  
  41.     public $defaultFormat = 11;
  42.  
  43.     const LANG_DFORMAT=10;
  44.     const LANG_DTFORMAT=11;
  45.     const LANG_TFORMAT=12;
  46.     const LANG_SHORT_DTFORMAT=13;
  47.     const LANG_SHORT_TFORMAT=14;
  48.     const DB_DFORMAT=20;
  49.     const DB_DTFORMAT=21;
  50.     const DB_TFORMAT=22;
  51.     const ISO8601_FORMAT=40;
  52.     const TIMESTAMP_FORMAT=50;
  53.     const RFC822_FORMAT=60;
  54.     const RFC2822_FORMAT=61;
  55.     const FULL_LANG_DATE=62;
  56.  
  57.     /**
  58.      *
  59.      */
  60.     function __construct($year=0$month=0$day=0$hour=0$minute=0$second=0){
  61.         $this->year = $year;
  62.         $this->month = $month;
  63.         $this->day = $day;
  64.         $this->hour = $hour;
  65.         $this->minute = $minute;
  66.         $this->second = $second;
  67.  
  68.         if(!$this->_check())
  69.         {
  70.           throw new jException('jelix~errors.datetime.invalid',
  71.               array($this->year$this->month$this->day,
  72.                 $this->hour$this->minute$this->second));
  73.         }
  74.     }
  75.  
  76.     /**
  77.      * Checks if the current jDateTime object is a valid gregorian date/time
  78.      * @return bool true if the date/time are valid.
  79.      */
  80.     private function _check({
  81.         // Only check the date if it is defined (eg. day, month and year are
  82.         // strictly positive).
  83.         if($this->day > && $this->month > && $this->year > 0
  84.             && !checkdate($this->month$this->day$this->year))
  85.         {
  86.             return false;
  87.         }
  88.         if(!(($this->second >= 0&& ($this->second < 60)
  89.             && ($this->minute >= 0&& ($this->minute < 60)
  90.             && ($this->hour >= 0&& ($this->hour < 24)))
  91.         {
  92.             return false;
  93.         }
  94.         return true;
  95.     }
  96.  
  97.      /**
  98.      * Check if jDateTime is "null" (all values egals to 0)
  99.      *
  100.      * @return boolean 
  101.      * @author Hadrien Lanneau (hadrien at over-blog dot com)
  102.      ***/
  103.     public function isNull({
  104.         return ($this->year === && $this->month === && $this->day === && $this->hour == && $this->minute == && $this->second == 0);
  105.     }
  106.  
  107.     /**
  108.      * Convert the date to a string format
  109.      * @param int $format one of the class constant xxx_FORMAT, or -1 if it should use the default format
  110.      * @return string the string date
  111.      * @see jDateTime:$defaultFormat
  112.      */
  113.     function toString($format=-1){
  114.         if($format==-1)
  115.             $format $this->defaultFormat;
  116.  
  117.         $str='';
  118.         switch($format){
  119.            case self::LANG_DFORMAT:
  120.                $t mktime $this->hour$this->minute,$this->second $this->month$this->day$this->year );
  121.                $lf jLocale::get('jelix~format.date');
  122.                $str date($lf$t);
  123.                break;
  124.            case self::LANG_DTFORMAT:
  125.                $t mktime $this->hour$this->minute,$this->second $this->month$this->day$this->year );
  126.                $lf jLocale::get('jelix~format.datetime');
  127.                $str date($lf$t);
  128.                break;
  129.            case self::LANG_TFORMAT:
  130.                $t mktime $this->hour$this->minute,$this->second 0);
  131.                $lf jLocale::get('jelix~format.time');
  132.                $str date($lf$t);
  133.                break;
  134.            case self::LANG_SHORT_DTFORMAT:
  135.                $t mktime $this->hour$this->minute,$this->second $this->month$this->day$this->year );
  136.                $lf jLocale::get('jelix~format.short_datetime');
  137.                $str date($lf$t);
  138.                break;
  139.            case self::LANG_SHORT_TFORMAT:
  140.                $t mktime $this->hour$this->minute,$this->second $this->month$this->day$this->year );
  141.                $lf jLocale::get('jelix~format.short_time');
  142.                $str date($lf$t);
  143.                break;
  144.            case self::DB_DFORMAT:
  145.                $str sprintf('%04d-%02d-%02d'$this->year$this->month$this->day);
  146.                break;
  147.            case self::DB_DTFORMAT:
  148.                $str sprintf('%04d-%02d-%02d %02d:%02d:%02d'$this->year$this->month$this->day$this->hour$this->minute$this->second);
  149.                break;
  150.            case self::DB_TFORMAT:
  151.                $str sprintf('%02d:%02d:%02d'$this->hour$this->minute$this->second);
  152.                break;
  153.            case self::ISO8601_FORMAT:
  154.                $str sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ'$this->year$this->month$this->day$this->hour$this->minute$this->second);
  155.                break;
  156.            case self::TIMESTAMP_FORMAT:
  157.                $str =(string) mktime $this->hour$this->minute,$this->second $this->month$this->day$this->year );
  158.                break;
  159.            case self::RFC822_FORMAT:
  160.            case self::RFC2822_FORMAT:
  161.                 $dt new DateTime('now'new DateTimeZone('UTC'));
  162.                 $dt->setDate($this->year$this->month$this->day);
  163.                 $dt->setTime($this->hour$this->minute,$this->second);
  164.                 $str $dt->format('r');
  165.                 break;
  166.            case self::FULL_LANG_DATE:
  167.                $t mktime $this->hour$this->minute,$this->second $this->month$this->day$this->year );
  168.                // month translation
  169.                $month jLocale::get('jelix~date_time.month.'.date('m',$t).'.label');
  170.                // day translation
  171.                $day jLocale::get('jelix~date_time.day.'.date('w',$t).'.label');
  172.                // get the date formatting
  173.                $lf jLocale::get('jelix~format.date_full');
  174.                // get the ordinal format of the day in the month especially for the English format (1st, 2nd, 3rd and th for the others)
  175.                $ordinal jLocale::get('jelix~date_time.day.'.$this->day.'.ordinal');
  176.                // put all this in the right order using the formatting string
  177.                $str sprintf($lf$day$this->day$ordinal$month$this->year);
  178.                break;
  179.         }
  180.        return $str;
  181.     }
  182.  
  183.     /**
  184.      * read a string to extract date values
  185.      * @param string $str the string date
  186.      * @param int $format one of the class constant xxx_FORMAT, or -1 if it should use the default format
  187.      * @see jDateTime:$defaultFormat
  188.      */
  189.     function setFromString($str,$format=-1){
  190.         if($format==-1){
  191.             $format $this->defaultFormat;
  192.         }
  193.         $this->year = 0;
  194.         $this->month = 0;
  195.         $this->day = 0;
  196.         $this->hour = 0;
  197.         $this->minute = 0;
  198.         $this->second = 0;
  199.         $ok=false;
  200.  
  201.         switch($format){
  202.            case self::LANG_DFORMAT:
  203.                $lf jLocale::get('jelix~format.date');
  204.                if ($res date_parse_from_format($lf$str)) {
  205.                    $ok=true;
  206.                    $this->year = $res['year'];
  207.                    $this->month = $res['month'];
  208.                    $this->day = $res['day'];
  209.                }
  210.                break;
  211.            case self::LANG_DTFORMAT:
  212.                $lf jLocale::get('jelix~format.datetime');
  213.                if ($res date_parse_from_format($lf$str)) {
  214.                    $ok=true;
  215.                    $this->year = $res['year'];
  216.                    $this->month = $res['month'];
  217.                    $this->day = $res['day'];
  218.                    $this->hour = $res['hour'];
  219.                    $this->minute = $res['minute'];
  220.                    $this->second = $res['second'];
  221.                }
  222.                break;
  223.            case self::LANG_TFORMAT:
  224.                $lf jLocale::get('jelix~format.time');
  225.                if ($res date_parse_from_format($lf$str)) {
  226.                    $ok=true;
  227.                    $this->hour = $res['hour'];
  228.                    $this->minute = $res['minute'];
  229.                    $this->second = $res['second'];
  230.                }
  231.                break;
  232.            case self::LANG_SHORT_TFORMAT:
  233.                $lf jLocale::get('jelix~format.short_time');
  234.                if($res date_parse_from_format($lf$str)){
  235.                    $ok=true;
  236.                    $this->hour = $res['hour'];
  237.                    $this->minute = $res['minute'];
  238.                    $this->second = 0;
  239.                }
  240.                break;
  241.            case self::LANG_SHORT_DTFORMAT:
  242.                $lf jLocale::get('jelix~format.short_datetime');
  243.                if ($res date_parse_from_format($lf$str)) {
  244.                    $ok=true;
  245.                    $this->year = $res['year'];
  246.                    $this->month = $res['month'];
  247.                    $this->day = $res['day'];
  248.                    $this->hour = $res['hour'];
  249.                    $this->minute = $res['minute'];
  250.                }
  251.                break;
  252.            case self::DB_DFORMAT:
  253.                if ($res date_parse_from_format("Y-m-d"$str)) {
  254.                    $ok=true;
  255.                    $this->year = $res['year'];
  256.                    $this->month = $res['month'];
  257.                    $this->day = $res['day'];
  258.                }
  259.                break;
  260.            case self::DB_DTFORMAT:
  261.                if ($res date_parse_from_format("Y-m-d H:i:s"$str)) {
  262.                    $ok=true;
  263.                    $this->year = $res['year'];
  264.                    $this->month = $res['month'];
  265.                    $this->day = $res['day'];
  266.                    $this->hour = $res['hour'];
  267.                    $this->minute = $res['minute'];
  268.                    $this->second = $res['second'];
  269.                }
  270.                break;
  271.            case self::DB_TFORMAT:
  272.                if ($res date_parse_from_format("H:i:s"$str)) {
  273.                    $ok=true;
  274.                    $this->hour = $res['hour'];
  275.                    $this->minute = $res['minute'];
  276.                    $this->second = $res['second'];
  277.                }
  278.                break;
  279.            case self::ISO8601_FORMAT:
  280.                if ($ok=preg_match('/^(\d{4})(?:\-(\d{2})(?:\-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{2,3}))?)?(Z|([+\-])(\d{2}):(\d{2})))?)?)?$/'$str$match)){
  281.                     $c count($match)-1;
  282.                     $this->year = intval($match[1]);
  283.                     if($c<2break;
  284.                     $this->month = intval($match[2]);
  285.                     if($c<3break;
  286.                     $this->day = intval($match[3]);
  287.                     if($c<4break;
  288.                     $this->hour = intval($match[4]);
  289.                     $this->minute = intval($match[5]);
  290.                     if($match[6!= ''$this->second = intval($match[6]);
  291.                     if($match[8!= 'Z'){
  292.                         $d new jDuration(array('hour'=>$match[10],'minute'=>$match[11]));
  293.                         if($match[9== '+')
  294.                             $this->sub($d);
  295.                         else
  296.                             $this->add($d);
  297.                     }
  298.                }
  299.                break;
  300.            case self::TIMESTAMP_FORMAT:
  301.                $ok=true;
  302.                $t getdate intval($str) );
  303.                $this->year = $t['year'];
  304.                $this->month = $t['mon'];
  305.                $this->day = $t['mday'];
  306.                $this->hour = $t['hours'];
  307.                $this->minute = $t['minutes'];
  308.                $this->second = $t['seconds'];
  309.                break;
  310.            case self::RFC822_FORMAT:
  311.            case self::RFC2822_FORMAT:
  312.                 $dt new DateTime($str);
  313.                 $dt $dt->setTimezone(new DateTimeZone('UTC'));
  314.                 $this->year = intval($dt->format('Y'));
  315.                 $this->month = intval($dt->format('m'));
  316.                 $this->day = intval($dt->format('d'));
  317.                 $this->hour = intval($dt->format('H'));
  318.                 $this->minute = intval($dt->format('i'));
  319.                 $this->second = intval($dt->format('s'));
  320.                 break;
  321.         }
  322.  
  323.         return $ok && $this->_check();
  324.     }
  325.  
  326.     /**
  327.      * Add a duration to the date.
  328.      * You can specify the duration in a jDuration object or give each value of
  329.      * the duration.
  330.      * @param jDuration/int $year the duration value or a year with 4 digits
  331.      * @param int $month month with 2 digits
  332.      * @param int $day day with 2 digits
  333.      * @param int $hour hour with 2 digits
  334.      * @param int $minute minute with 2 digits
  335.      * @param int $second second with 2 digits
  336.      */
  337.     public function add($year$month=0$day=0$hour=0$minute=0$second=0{
  338.         if ($year instanceof jDuration{
  339.             $dt $year;
  340.         else {
  341.             $dt new jDuration(array("year" => $year"month" => $month,
  342.                 "day" => $day"hour" => $hour"minute" => $minute,
  343.                 "second" => $second));
  344.         }
  345.         $t mktime($this->hour$this->minute$this->second + $dt->seconds,
  346.              $this->month + $dt->months$this->day + $dt->days$this->year);
  347.  
  348.         $t getdate ($t);
  349.         $this->year = $t['year'];
  350.         $this->month = $t['mon'];
  351.         $this->day = $t['mday'];
  352.         $this->hour = $t['hours'];
  353.         $this->minute = $t['minutes'];
  354.         $this->second = $t['seconds'];
  355.     }
  356.  
  357.     /**
  358.      * substract a <b>duration</b> to the date
  359.      * You can specify the duration in a jDuration object or give each value of
  360.      * the duration.
  361.      * @param jDuration/int $year the duration value or a year with 4 digits
  362.      * @param int $month month with 2 digits
  363.      * @param int $day day with 2 digits
  364.      * @param int $hour hour with 2 digits
  365.      * @param int $minute minute with 2 digits
  366.      * @param int $second second with 2 digits
  367.      */
  368.     public function sub($year$month=0$day=0$hour=0$minute=0$second=0{
  369.         if ($year instanceof jDuration{
  370.             $dt $year;
  371.         else {
  372.             $dt new jDuration(array("year" => $year"month" => $month,
  373.                 "day" => $day"hour" => $hour"minute" => $minute,
  374.                 "second" => $second));
  375.         }
  376.         $dt->mult(-1);
  377.         $this->add($dt);
  378.     }
  379.  
  380.     /**
  381.      * to know the duration between two dates.
  382.      * @param jDateTime $dt  the date on which a sub will be made with the date on the current object
  383.      * @param bool $absolute 
  384.      * @return jDuration a jDuration object
  385.      */
  386.     public function durationTo($dt$absolute=true){
  387.         if($absolute){
  388.             $t gmmktime($dt->hour$dt->minute$dt->second,
  389.                 $dt->month$dt->day$dt->year)
  390.                 - gmmktime($this->hour$this->minute$this->second,
  391.                     $this->month$this->day$this->year);
  392.             return new jDuration($t);
  393.         }
  394.         else{
  395.             return new jDuration(array(
  396.                 "year" => $dt->year $this->year,
  397.                 "month" => $dt->month $this->month,
  398.                 "day" => $dt->day $this-> day,
  399.                 "hour" => $dt->hour $this->hour,
  400.                 "minute" => $dt->minute $this->minute,
  401.                 "second" => $dt->second $this->second
  402.             ));
  403.         }
  404.     }
  405.  
  406.     /**
  407.      * Compare two date
  408.      * @param jDateTime $dt the date to compare
  409.      * @return integer -1 if $dt > $this, 0 if $dt = $this, 1 if $dt < $this
  410.      */
  411.     public function compareTo($dt){
  412.         $fields=array('year','month','day','hour','minute','second');
  413.         foreach($fields as $field){
  414.             if($dt->$field $this->$field)
  415.                 return -1;
  416.             if($dt->$field $this->$field)
  417.                 return 1;
  418.         }
  419.         return 0;
  420.     }
  421.  
  422.     /**
  423.     * Set date to current datetime
  424.     */
  425.     public function now({
  426.         $this->year = intval(date('Y'));
  427.         $this->month = intval(date('m'));
  428.         $this->day = intval(date('d'));
  429.         $this->hour = intval(date('H'));
  430.         $this->minute = intval(date('i'));
  431.         $this->second = intval(date('s'));
  432.     }
  433.  
  434.  
  435.     /**
  436.     * Substract a date with another
  437.     * @param jDateTime $date 
  438.     * @return jDateTime 
  439.     * @author Hadrien Lanneau <hadrien@over-blog.com>
  440.     * @since 1.2
  441.     */
  442.     public function substract($date null{
  443.         if (!$date{
  444.             $date new jDateTime();
  445.             $date->now();
  446.         }
  447.  
  448.         $newDate new jDateTime();
  449.  
  450.         $items array(
  451.                 'second',
  452.                 'minute',
  453.                 'hour',
  454.                 'day',
  455.                 'month',
  456.                 'year'
  457.             );
  458.  
  459.         foreach ($items as $k => $i{
  460.             $newDate->{$i$date->{$i$this->{$i};
  461.             if ($newDate->{$i0{
  462.                 switch ($i{
  463.                     case 'second':
  464.                     case 'minute':
  465.                         $sub 60;
  466.                         break;
  467.                     case 'hour':
  468.                         $sub 24;
  469.                         break;
  470.                     case 'day':
  471.                         switch ($this->month{
  472.                             // Month with 31 days
  473.                             case 1:
  474.                             case 3:
  475.                             case 5:
  476.                             case 7:
  477.                             case 8:
  478.                             case 10:
  479.                             case 12:
  480.                                 $sub 31;
  481.                                 break;
  482.                             // Month with 30 days
  483.                             case 4:
  484.                             case 6:
  485.                             case 9:
  486.                             case 11:
  487.                                 $sub 30;
  488.                                 break;
  489.                             // February
  490.                             case 2:
  491.                                 if ($this->year == and
  492.                                         !(
  493.                                                 $this->year 100 == and
  494.                                                 $this->year 400 != 0
  495.                                         )) {
  496.                                     // Bissextile
  497.                                     $sub 29;
  498.                                 }
  499.                                 else {
  500.                                    $sub 28;
  501.                                 }
  502.                                 break;
  503.                         }
  504.                         break;
  505.                     case 'month':
  506.                         $sub 12;
  507.                         break;
  508.                     default:
  509.                         $sub 0;
  510.                 }
  511.                 $newDate->{$iabs($sub $newDate->{$i});
  512.                 if (isset($items[$k+1])) {
  513.                     $newDate->{$items[$k+1]}--;
  514.                 }
  515.             }
  516.         }
  517.         return $newDate;
  518.     }
  519. }

Documentation generated on Wed, 04 Jan 2017 22:53:39 +0100 by phpDocumentor 1.4.3