What can use for DateTime::diff() for PHP 5.2?

后端 未结 10 1575
情歌与酒
情歌与酒 2020-11-27 06:18

Is there any function equivalent to DateTime::diff() in PHP 5.2?

My local server is PHP 5.3 and using DateTime::diff(). then I found that my live site uses PHP 5.2 a

相关标签:
10条回答
  • 2020-11-27 06:37

    I just needed that ( unfortunately ) for a WordPress plugin. This I use the function in 2 times:

    1. In my class calling ->diff() ( my class extends DateTime, so $this is the reference DateTime )

      function diff ($secondDate){
          $firstDateTimeStamp = $this->format("U");
          $secondDateTimeStamp = $secondDate->format("U");
          $rv = ($secondDateTimeStamp - $firstDateTimeStamp);
          $di = new DateInterval($rv);
          return $di;
      }
      
    2. Then I recreated a fake DateInterval class ( because DateInterval is only valid in PHP >= 5.3 ) as follows:

      Class DateInterval {
          /* Properties */
          public $y = 0;
          public $m = 0;
          public $d = 0;
          public $h = 0;
          public $i = 0;
          public $s = 0;
      
          /* Methods */
          public function __construct ( $time_to_convert /** in seconds */) {
              $FULL_YEAR = 60*60*24*365.25;
              $FULL_MONTH = 60*60*24*(365.25/12);
              $FULL_DAY = 60*60*24;
              $FULL_HOUR = 60*60;
              $FULL_MINUTE = 60;
              $FULL_SECOND = 1;
      
      //        $time_to_convert = 176559;
              $seconds = 0;
              $minutes = 0;
              $hours = 0;
              $days = 0;
              $months = 0;
              $years = 0;
      
              while($time_to_convert >= $FULL_YEAR) {
                  $years ++;
                  $time_to_convert = $time_to_convert - $FULL_YEAR;
              }
      
              while($time_to_convert >= $FULL_MONTH) {
                  $months ++;
                  $time_to_convert = $time_to_convert - $FULL_MONTH;
              }
      
              while($time_to_convert >= $FULL_DAY) {
                  $days ++;
                  $time_to_convert = $time_to_convert - $FULL_DAY;
              }
      
              while($time_to_convert >= $FULL_HOUR) {
                  $hours++;
                  $time_to_convert = $time_to_convert - $FULL_HOUR;
              }
      
              while($time_to_convert >= $FULL_MINUTE) {
                  $minutes++;
                  $time_to_convert = $time_to_convert - $FULL_MINUTE;
              }
      
              $seconds = $time_to_convert; // remaining seconds
              $this->y = $years;
              $this->m = $months;
              $this->d = $days;
              $this->h = $hours;
              $this->i = $minutes;
              $this->s = $seconds;
          }
      }
      

    Hope that helps somebody.

    0 讨论(0)
  • 2020-11-27 06:37

    I was trying to improve Christopher Pickslay's answer.

    I made this function that returns and object with most of the properties from the original DateInterval object.

    There is no "days" property, because it seems to be some bug in my test server (it always return 6015) .

    Also, I am assuming every month has 30 days, which is definitely not precise, but may help.

    function dateTimeDiff($date1, $date2) {
    
        $alt_diff = new stdClass();
        $alt_diff->y =  floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24*365));
        $alt_diff->m =  floor((floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365))/30);
        $alt_diff->d =  floor(floor(abs($date1->format('U') - $date2->format('U')) / (60*60*24)) - ($alt_diff->y * 365) - ($alt_diff->m * 30));
        $alt_diff->h =  floor( floor(abs($date1->format('U') - $date2->format('U')) / (60*60)) - ($alt_diff->y * 365*24) - ($alt_diff->m * 30 * 24 )  - ($alt_diff->d * 24) );
        $alt_diff->i = floor( floor(abs($date1->format('U') - $date2->format('U')) / (60)) - ($alt_diff->y * 365*24*60) - ($alt_diff->m * 30 * 24 *60)  - ($alt_diff->d * 24 * 60) -  ($alt_diff->h * 60) );
        $alt_diff->s =  floor( floor(abs($date1->format('U') - $date2->format('U'))) - ($alt_diff->y * 365*24*60*60) - ($alt_diff->m * 30 * 24 *60*60)  - ($alt_diff->d * 24 * 60*60) -  ($alt_diff->h * 60*60) -  ($alt_diff->i * 60) );
        $alt_diff->invert =  (($date1->format('U') - $date2->format('U')) > 0)? 0 : 1 ;
    
        return $alt_diff;
    }    
    
    0 讨论(0)
  • 2020-11-27 06:39

    Spudley was close, but you need to use gmdate not date.

    So this works for 24 hours or less (if it's a positive value at least):

    $difference = $date2->format('U') - $date1->format('U');
    $time_diff = gmdate('H:i:s',$difference);
    
    0 讨论(0)
  • 2020-11-27 06:40

    Here is the best solution for your question.

    <?php
    
    /* Find difference between two dates in days. PHP 5.2.x.  */
    
    $d1 = date('Y-m-d', strtotime('2013-06-13'));
    $d2 = date("Y-m-d");
    echo diff($d1, $d2);
    
    function diff($date1, $date2) {
        $diff = abs(strtotime($date2) - strtotime($date1));
        $years = floor($diff / (365*60*60*24));
        $months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
        $days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24) / (60*60*24));
        return $days;
    }
    ?>
    
    0 讨论(0)
  • 2020-11-27 06:42

    Please observe that if your DateTime object was created from a date string without any timezone information (as in '2012-01-01 05:00:00' like from mysql), then setting the timezone later with DateTimeZone objects via setTimeZone() does not change the DateTime objects internal timestamp.

    $localtime = new DateTime('2012-01-01 08:00:00+02:00'); // Europe/Copenhagen (+ daylight savings)
    $localtime->setTimezone(new DateTimeZone('UTC')); // convert local time to utc
    
    $utctime = new DateTime('2012-01-01 06:00:00'); // timezone assumed utc, but is in fact unknown
    $utctime->setTimezone(new DateTimeZone('UTC')); // trying to rectify missing timezone which fails, because the internal timestamp isn't modified, although any other format than 'U' may indicate so
    #$utctime = new DateTime('2012-01-01 06:00:00+00:00'); // timezone stated, this works
    
    $diff = intval($localtime->format('U')) - intval($utctime->format('U'));
    echo $diff; // expecting zero
    
    0 讨论(0)
  • 2020-11-27 06:49

    Yes, it's annoying that feature didn't make it into PHP5.2.

    I'll assume you can't upgrade to 5.3? You should look into it; there's very little reason not to upgrade; but I'll assume you can't for whatever the reason.

    First tip: If you only need a diff of less than 24hours, you can simply subtract the two time stamps, and do $time_diff = date('H:i:s',$subtracted_value);

    If you're doing more than 24 hour diffs, but you're okay with just returning the number of days along with the time difference, you can expand on the above technique by doing a modulus calculation on the subtrated value, against the number of seconds in a day (ie 24*60*60, which is 86400)

    $subtracted_value = $date1 - $date2;
    $days_diff = $subtracted_value % 86400;
    $time_diff = date('H:i:s',$subtracted_value);
    

    If you need weeks, you can of course do $days_diff % 7.

    Unfortunately, the manual technique breaks down after weeks, because months and years are variable in length (technically days are too, given daylight saving, but you can probably ignore that, especially as you're only ever going to be one hour out, at the most), but hopefully that's good enough to get you started.

    0 讨论(0)
提交回复
热议问题