i write a date calculator, but there always get a one-day-distance wrong

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Gucci

    i write a date calculator, but there always get a one-day-distance wrong

    <?php
    /**
    * check ine year is a leap year, and return the month day array
    *
    * @param int $year **the year must bigger than zero**
    * @return array
    */
    function is_leap_year($y ear){
    $year=floor($ye ar);
    if ($year<=0) {
    return false;
    }
    $flag = false;//leap year flag

    /*
    * check the year
    */
    if ($year%100==0) {
    if ($year%400==0) {
    $flag = true;
    }
    }
    else {
    if ($year%4==0) {
    $flag = true;
    }
    }
    $mon[0] = $flag;//leap year flag
    $mon[1] = 31;
    $mon[2] = $flag?29:28;
    $mon[3] = 31;
    $mon[4] = 30;
    $mon[5] = 31;
    $mon[6] = 30;
    $mon[7] = 31;
    $mon[8] = 31;
    $mon[9] = 30;
    $mon[10] = 31;
    $mon[11] = 30;
    $mon[12] = 31;
    return $mon;
    }

    /**
    * read a datetime string and explode it in to an array
    * string format: YY-M-D h:m:s
    *
    * @param string $datetime
    * @return array
    */
    function get_date_time($ datetime){
    $current = explode(' ', $datetime);
    $date = $current[0];
    $time = $current[1];
    $date_tmp = explode('-',$date);
    $time_tmp = explode(':',$ti me);
    $current['year'] = $date_tmp[0]+0;
    $current['month'] = $date_tmp[1]+0;
    $current['day'] = $date_tmp[2]+0;
    $current['hour'] = $time_tmp[0]+0;
    $current['minute'] = $time_tmp[1]+0;
    $current['second'] = $time_tmp[2]+0;
    return $current;
    }

    /**
    * calculate the datetime
    *
    *
    * @param string $datetime //string format: YY-M-D h:m:s
    * @param array $diff //time stamp
    * array('year'=>i nt, 'month'=>int, 'day'=>int,
    * 'hour'=>int, 'minute'=>int,' second'=>int)
    * @return string //result string format: YYYY-MM-DD
    hh:mm:ss
    */
    function date_diff($date time, $diff){
    $current = get_date_time($ datetime); //get the init time stamp
    if($curent['year']<1){
    return false;
    }
    $mon = is_leap_year($c urrent['year']); // get the current month
    days

    /*
    * init
    */
    $second_tmp = $current['second']+$diff['second'];
    $minute_tmp = $current['minute']+$diff['minute'];
    $hour_tmp = $current['hour']+$diff['hour'];
    $year_tmp = $current['year']+$diff['year'];
    $month_tmp = $current['month']+$diff['month'];
    $day_tmp=$curre nt['day']+$diff['day'];

    /*
    * convert the TIME stamp into seconds
    */
    $hour_tmp = $hour_tmp*60*60 ;
    $minute_tmp = $minute_tmp*60;
    $second_tmp = $hour_tmp+$minu te_tmp+$second_ tmp;
    //convert the seconds into (day + second), the second couldn't be
    negative
    if ($second_tmp<0) {
    $day = intval($second_ tmp/(24*60*60))-1;
    }
    else {
    $day = intval($second_ tmp/(24*60*60));
    }
    $day_tmp=$curre nt['day']+$diff['day']+$day;
    $second_tmp = $second_tmp-($day*24*60*60) ;

    /*
    * convert the seconds into h:m:s
    */
    $hour_tmp = intval($second_ tmp/(60*60));
    $second_tmp = $second_tmp-($hour_tmp*60*6 0);
    $minute_tmp = intval($second_ tmp/(60));
    $second_tmp = $second_tmp-($minute_tmp*60 );

    /*
    * month caculate
    */
    if ($month_tmp<0) {
    while ($month_tmp<1) {
    $year_tmp--;
    $month_tmp+=12;
    }
    }
    else {
    while ($month_tmp>12) {
    $year_tmp++;
    $month_tmp-=12;
    }
    }

    /*
    * day caculate
    */
    if ($day_tmp<0) {
    while ($day_tmp<1) {
    $month_tmp--;
    if ($month_tmp<1) {
    $year_tmp--;
    $month_tmp=12;
    $mon = is_leap_year($y ear_tmp);
    }
    $day_tmp+=$mon[$month_tmp];
    }
    }
    else {
    while ($day_tmp>$mon[$month_tmp]){
    $day_tmp-=$mon[$month_tmp];
    $month_tmp++;
    if ($month_tmp>12) {
    $year_tmp++;
    $month_tmp=1;
    $mon = is_leap_year($y ear_tmp);
    }
    }
    }
    if ($year_tmp<=0) { return false; }
    if ($month_tmp<10) { $month_tmp='0'. $month_tmp; }
    if ($day_tmp<10) { $day_tmp='0'.$d ay_tmp; }
    if ($hour_tmp<10) { $hour_tmp='0'.$ hour_tmp; }
    if ($minute_tmp<10 ){ $minute_tmp='0' .$minute_tmp; }
    if ($second_tmp<10 ){ $second_tmp='0' .$second_tmp; }
    $str_date = $year_tmp.'-'.$month_tmp.'-'.$day_tmp.'
    '.$hour_tmp.':' .$minute_tmp.': '.$second_tmp;
    return $str_date;
    }

    /**
    * Run date_diff()
    **/
    $diff['year'] = -10;
    $diff['month'] = -100;
    $diff['day'] = -500;
    $diff['hour'] = -98;
    $diff['minute'] = -237;
    $diff['second'] = -999;
    echo date_diff('2000-1-1 0:0:0',$diff)." \n";
    echo date("Y-m-d H:i:s",mktime(0-98, 00-237, 0-999, 1-100, 1-500,
    2000-10))."\n";
    echo "\n";

    $diff['year'] = 0;
    $diff['month'] = 0;
    $diff['day'] = -500;
    $diff['hour'] = -98;
    $diff['minute'] = 0;
    $diff['second'] = 0;
    echo date_diff('2000-1-1 0:0:0',$diff)." \n";
    echo date("Y-m-d H:i:s",mktime(0-98, 00-0, 0-0, 1-0, 1-500,
    2000-0))."\n";
    ?>

    the result
    =============== =============== ===========
    1980-04-15 17:46:21
    1980-04-14 17:46:21

    1998-08-14 22:00:00
    1998-08-14 22:00:00

    please tell me what's wrong,
    thanks!

    Gucci Koo

  • .::[ikciu]::.

    #2
    Re: i write a date calculator, but there always get a one-day-distance wrong

    Zebrawszy my?li Gucci <jueljust@gmail .comwyklepa?:

    /**
    * check ine year is a leap year, and return the month day array
    *
    * @param int $year **the year must bigger than zero**
    * @return array
    */

    OMG man, you should to rewrite this code...

    1. try to use date("L") for leap year
    2. too much of code
    3. same solution for other functions....



    --
    ~~~~~~~~~~~~~~~ ~~~~~~~~~~
    ..::[ ikciu ]::.
    gg: 718845
    www: e-irsa.pl


    Comment

    • Paul Lautman

      #3
      Re: i write a date calculator, but there always get a one-day-distance wrong

      This is usually because there is the North American Daylight Savings time
      built in to PHP.

      Why write one yourself when there are loads already written?


      Comment

      • Gucci

        #4
        Re: i write a date calculator, but there always get a one-day-distance wrong

        has i have to calculate the datetime which beyond the unixtime on
        32-bit server

        Comment

        • R. Rajesh Jeba Anbiah

          #5
          |OT|Re: i write a date calculator, but there always get a one-day-distance wrong

          Gucci wrote:
          <?php
          /**
          * check ine year is a leap year, and return the month day array
          *
          * @param int $year **the year must bigger than zero**
          * @return array
          */
          function is_leap_year($y ear){
          $year=floor($ye ar);
          if ($year<=0) {
          return false;
          }
          $flag = false;//leap year flag
          >
          /*
          * check the year
          */
          if ($year%100==0) {
          if ($year%400==0) {
          $flag = true;
          }
          }
          else {
          if ($year%4==0) {
          $flag = true;
          }
          }
          $mon[0] = $flag;//leap year flag
          $mon[1] = 31;
          $mon[2] = $flag?29:28;
          $mon[3] = 31;
          $mon[4] = 30;
          $mon[5] = 31;
          $mon[6] = 30;
          $mon[7] = 31;
          $mon[8] = 31;
          $mon[9] = 30;
          $mon[10] = 31;
          $mon[11] = 30;
          $mon[12] = 31;
          return $mon;
          }
          <snip>

          FWIW, this is one of many reasons why everyone should read K&R.

          --
          <?php echo 'Just another PHP saint'; ?>
          Email: rrjanbiah-at-Y!com Blog: http://rajeshanbiah.blogspot.com/

          Comment

          • Gucci

            #6
            Re: i write a date calculator, but there always get a one-day-distance wrong

            i solve the problem

            <?php
            function get_date_time($ datetime){
            if (!$datetime) {
            return false;
            }
            $current = explode(' ', $datetime);
            $date = $current[0];
            $time = $current[1];
            $date_tmp = explode('-',$date);
            $time_tmp = explode(':',$ti me);
            $current['year'] = $date_tmp[0]+0;
            $current['month'] = $date_tmp[1]+0;
            $current['day'] = $date_tmp[2]+0;
            $current['hour'] = $time_tmp[0]+0;
            $current['minute'] = $time_tmp[1]+0;
            $current['second'] = $time_tmp[2]+0;
            return $current;
            }

            function get_time_stamp( $stamp_array){
            if (!$stamp_array) {
            return false;
            }
            $diff['year'] = $stamp_array[0];
            $diff['month'] = $stamp_array[1];
            $diff['day'] = $stamp_array[2];
            $diff['hour'] = $stamp_array[3];
            $diff['minute'] = $stamp_array[4];
            $diff['second'] = $stamp_array[5];
            return $diff;
            }

            function is_leap_year($y ear){
            $year=floor($ye ar);
            if ($year<=0) {
            return false;
            }
            $flag = false;

            if ($year%100==0) {
            if ($year%400==0) {$flag = true;}
            }
            else {
            if ($year%4==0) {$flag = true;}
            }
            $mon = array($flag,31, ($flag?29:28),3 1,30,31,30,31,3 1,30,31,30,31);
            return $mon;
            }

            function date_calc($stam p,&$litter,&$bi gger){
            $time_name=arra y('second','min ute','hour','da y','month','yea r');
            $time_base=arra y(60,60,24,null ,12,null);
            $position = array_search($s tamp,$time_name );

            $bigger_tmp = intval($litter/$time_base[$position]);
            if ($bigger_tmp<0) {
            $bigger_tmp--;
            }
            $litter = $litter-$bigger_tmp*$ti me_base[$position];
            $bigger+=$bigge r_tmp;
            }

            function date_diff($star t,$diff_stamp){
            $current = get_date_time($ start);
            $diff = get_time_stamp( $diff_stamp);

            /*
            * IMPORTANT!!!
            * MAKE ALL TIMESTAMP START AT ZERO
            */
            $current['year']--;
            $current['month']--;
            $current['day']--;

            $year = $current['year']+$diff['year'];
            $month = $current['month']+$diff['month'];
            $day = $current['day']+$diff['day'];
            $hour = $current['hour']+$diff['hour'];
            $minute = $current['minute']+$diff['minute'];
            $second = $current['second']+$diff['second'];

            date_calc('seco nd',$second,$mi nute);
            date_calc('minu te',$minute,$ho ur);
            date_calc('hour ',$hour,$day);
            date_calc('mont h',$month,$year );

            $year++;
            $month++;
            $day++;

            $mon = is_leap_year($y ear);
            if ($day<0) {
            while ($day<1) {
            $month--;
            if ($month<1) {
            $year--;
            $month=12;
            $mon = is_leap_year($y ear);
            }
            $day+=$mon[$month];
            }
            }
            else {
            while ($day>$mon[$month]){
            $day-=$mon[$month];
            $month++;
            if ($month>12){
            $year++;
            $month=1;
            $mon = is_leap_year($y ear);
            }
            }
            }

            if ($month<10) {$month='0'.$mo nth;}
            if ($day<10) {$day='0'.$day; }
            if ($hour<10) {$hour='0'.$hou r;}
            if ($minute<10) {$minute='0'.$m inute;}
            if ($second<10) {$second='0'.$s econd;}
            return "$year-$month-$day $hour:$minute:$ second";
            }
            ?>

            Comment

            • Steve

              #7
              Re: i write a date calculator, but there always get a one-day-distance wrong

              On Sun, 27 Aug 2006 06:36:09 -0700, Gucci wrote:
              if ($year%100==0) {
              if ($year%400==0) {$flag = true;}
              Are you *sure* this logic is correct? I'm not... and if it is, why bother
              with the check for 100 years?

              Comment

              • Jerry Stuckle

                #8
                Re: i write a date calculator, but there always get a one-day-distancewrong

                Steve wrote:
                On Sun, 27 Aug 2006 06:36:09 -0700, Gucci wrote:
                >
                >
                > if ($year%100==0) {
                > if ($year%400==0) {$flag = true;}
                >
                >
                Are you *sure* this logic is correct? I'm not... and if it is, why bother
                with the check for 100 years?
                >
                Yes, that is correct.

                It is a leap year if the year is divisible by 400, or if its divisible
                by 4 and not by 100.

                He needs the $year % 100 for the else clause.


                --
                =============== ===
                Remove the "x" from my email address
                Jerry Stuckle
                JDS Computer Training Corp.
                jstucklex@attgl obal.net
                =============== ===

                Comment

                Working...