php date_diff计数错误

时间:2019-04-23 15:40:57

标签: php datediff

我在2015年3月1日和2017年1月31日进行日期比较(使用php7.2),它返回1年11个月零2天。但应该(显然)应该是11个月零天或10个月零30天。

那是为什么?请不要告诉我,php被30左右除数-如果它不如手动解决方案可靠,我就不需要日历功能!..那太疯狂了,对吧?

$diff = date_create('2015-03-01')->diff(date_create('2017-01-31'));
// returns
DateInterval Object
(
    [y] => 1
    [m] => 11
    [d] => 2
    [h] => 0
    [i] => 0
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 702
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
// and that's simply just wrong

更新 在将时区从“欧洲/柏林”切换为“ UTC”时可以使用

date_default_timezone_set('UTC');

但是,是的,'欧洲/柏林'也应该有效...

2 个答案:

答案 0 :(得分:0)

在阅读php.net文档comments about this function时,我发现了一个似乎可行的解决方案。有人重写了PHP 5.2和更早版本的diff()函数。

结果: 1年10个月30天(但您可以对其进行修改以包括所有内容)

绝对不是最优雅的解决方案,但我希望这会有所帮助。

<?php

echo get_timespan_string(new Datetime('2015-03-01'), new Datetime('2017-01-31'));

function get_timespan_string($older, $newer) { 
  $Y1 = $older->format('Y'); 
  $Y2 = $newer->format('Y'); 
  $Y = $Y2 - $Y1; 

  $m1 = $older->format('m'); 
  $m2 = $newer->format('m'); 
  $m = $m2 - $m1; 

  $d1 = $older->format('d'); 
  $d2 = $newer->format('d'); 
  $d = $d2 - $d1; 

  $H1 = $older->format('H'); 
  $H2 = $newer->format('H'); 
  $H = $H2 - $H1; 

  $i1 = $older->format('i'); 
  $i2 = $newer->format('i'); 
  $i = $i2 - $i1; 

  $s1 = $older->format('s'); 
  $s2 = $newer->format('s'); 
  $s = $s2 - $s1; 

  if($s < 0) { 
    $i = $i -1; 
    $s = $s + 60; 
  } 
  if($i < 0) { 
    $H = $H - 1; 
    $i = $i + 60; 
  } 
  if($H < 0) { 
    $d = $d - 1; 
    $H = $H + 24; 
  } 
  if($d < 0) { 
    $m = $m - 1; 
    $d = $d + get_days_for_previous_month($m2, $Y2); 
  } 
  if($m < 0) { 
    $Y = $Y - 1; 
    $m = $m + 12; 
  } 
  $timespan_string = create_timespan_string($Y, $m, $d, $H, $i, $s); 
  return $timespan_string; 
} 

function get_days_for_previous_month($current_month, $current_year) { 
  $previous_month = $current_month - 1; 
  if($current_month == 1) { 
    $current_year = $current_year - 1; //going from January to previous December 
    $previous_month = 12; 
  } 
  if($previous_month == 11 || $previous_month == 9 || $previous_month == 6 || $previous_month == 4) { 
    return 30; 
  } 
  else if($previous_month == 2) { 
    if(($current_year % 4) == 0) { //remainder 0 for leap years 
      return 29; 
    } 
    else { 
      return 28; 
    } 
  } 
  else { 
    return 31; 
  } 
} 

function create_timespan_string($Y, $m, $d, $H, $i, $s) 
{ 
  $timespan_string = ''; 
  $found_first_diff = false; 
  if($Y >= 1) { 
    $found_first_diff = true; 
    $timespan_string .= pluralize($Y, 'year').' '; 
  } 
  if($m >= 1 || $found_first_diff) { 
    $found_first_diff = true; 
    $timespan_string .= pluralize($m, 'month').' '; 
  } 
  if($d >= 1 || $found_first_diff) { 
    $found_first_diff = true; 
    $timespan_string .= pluralize($d, 'day').' '; 
  } 
  if($H >= 1 || $found_first_diff) { 
    $found_first_diff = true; 
    $timespan_string .= pluralize($H, 'hour').' '; 
  } 
  if($i >= 1 || $found_first_diff) { 
    $found_first_diff = true; 
    $timespan_string .= pluralize($i, 'minute').' '; 
  } 
  if($found_first_diff) { 
    $timespan_string .= 'and '; 
  } 
  $timespan_string .= pluralize($s, 'second'); 
  return $timespan_string; 
} 

function pluralize( $count, $text ) 
{ 
  return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) ); 
}

答案 1 :(得分:0)

这只是一个错误。已知,古老,从未解决。至少在2017年重新开放...

PHP DateTime Timedifference only correct in UTC Timezone?