简体   繁体   English

PHP的日期时间->差异

[英]PHP DateTime->diff

I was going through a php code today and found this to be really weird. 我今天正在检查一个php代码,发现这真的很奇怪。

<?php
  $now = new DateTime("2015-07-29 03:38:55");
  $previous = new DateTime("2013-07-29 05:06:40");
  $diff = $now->diff($previous);
  $diff2 = $previous->diff($now);

  printf("%d years, %d month, %d days, %d hours, %d minutes %d seconds.<br/>", $diff->y, $diff->m, $diff->d, $diff->h, $diff->i, $diff->s);
  printf('%d years, %d month, %d days, %d hours, %d minutes %d seconds', $diff->y, $diff->m, $diff2->d, $diff2->h, $diff2->i, $diff2->s);

The output is 输出是

1 years, 11 month, 30 days, 22 hours, 32 minutes 15 seconds 1年11个月30天22小时32分15秒

1 years, 11 month, 29 days, 22 hours, 32 minutes 15 seconds 1年11个月29天22小时32分15秒

I have two questions 我有两个问题

  1. I read the document it said that $previous->diff($now); 我阅读了文档,上面写着$previous->diff($now); shows $now - $previous . 显示$now $previous However, if it is the other way around, wouldn't it be negative? 但是,如果相反,这是否定的呢?

  2. Why is one 30 days and the other is 29 days? 为什么一个是30天,另一个是29天?

I have a speculation that this could be due to the invert. 我推测这可能是由于反转造成的。 I'm not entirely sure why it is adding an extra day... but a quick change I did was: 我不完全确定为什么要增加额外的一天...但是我做的一个快速更改是:

$now = new DateTime("2015-07-29 03:38:55");
$previous = new DateTime("2013-07-29 05:06:40");

$diff = $now->diff($previous);
$diff2 = $previous->diff($now);

printf("%d years, %d month, %d days, %d hours, %d minutes %d seconds\r\n", $diff->y, $diff->m, ($diff->d - $diff->invert), $diff->h, $diff->i, $diff->s);
printf('%d years, %d month, %d days, %d hours, %d minutes %d seconds', $diff->y, $diff->m, ($diff2->d - $diff2->invert), $diff2->h, $diff2->i, $diff2->s);

And the output is: 输出为:

1 years, 11 month, 29 days, 22 hours, 32 minutes 15 seconds
1 years, 11 month, 29 days, 22 hours, 32 minutes 15 seconds

Or, alternatively, the above is completely wrong and is just a coincidence... another explanation may be that the diff days was a float value for $diff , and so it was rounded down... yielding 29 days. 或者,上面的说法是完全错误的,只是一个巧合...另一个解释可能是diff days是$diff的浮点值,因此将其四舍五入...产生29天。 Possible leap-year issue as well. 可能还有leap年问题。

Edit 编辑

The above is also wrong... if you change the output to floats, it will show whole numbers. 上面的方法也是错误的...如果将输出更改为float,它将显示整数。 This adds to the confusion. 这加剧了混乱。 I'll leave this answer to possibly help someone else figure out the solution. 我将保留此答案,以帮助其他人找出解决方案。

$now = new DateTime("2015-07-29 03:38:55", new DateTimeZone('GMT'));
$previous = new DateTime("2013-07-29 05:06:40", new DateTimeZone('GMT'));

$diff = $now->diff($previous);
$diff2 = $previous->diff($now);

printf("%f years, %f month, %f days, %f hours, %f minutes %f seconds %f total days\r\n", $diff->y, $diff->m, $diff->d, $diff->h, $diff->i, $diff->s, $diff->days);
printf('%f years, %f month, %f days, %f hours, %f minutes %f seconds %f total days', $diff->y, $diff->m, $diff2->d, $diff2->h, $diff2->i, $diff2->s, $diff2->days);

I even set the timezone in hopes to help. 我什至设置了时区,希望对您有所帮助。 Still yields whole numbers: 仍然产生整数:

1.000000 years, 11.000000 month, 30.000000 days, 22.000000 hours, 32.000000 minutes 15.000000 seconds 729.000000 total days
1.000000 years, 11.000000 month, 29.000000 days, 22.000000 hours, 32.000000 minutes 15.000000 seconds 729.000000 total days
  1. the sign of the difference is in the invert property: $diff->invert =1 and $diff2->invert =0 差异的符号在invert属性中: $diff->invert = 1和$diff2->invert = 0
  2. You can see in the php source here a day correction by 1 when: 您可以在此处的php源代码中看到以下情况下每天的修正1:
    1. the 1st of the dates is in DST and the 2nd is not 日期的第一天是夏令时,第二天不是
    2. the timestamp of the 2nd date starts after the timetstamp of the 1st one without the DST correction 第二个日期的时间戳记在第一个日期的时间戳记之后 经过DST校正而开始
    3. the timestamp of the 2nd date starts before the timetstamp of the 1st one with the DST correction 第二个日期的时间戳开始 具有 DST校正的第一个日期的时间戳之前

This is what is causing one to show 30 days and the other to show 29. In @Half Crazed's example, both dates are in DST, so no correction there. 这就是导致一个显示30天而另一个显示29天的原因。在@Half Crazed的示例中,两个日期都在DST中,因此那里没有更正。 If the previous date of the OP were 2013-07-29 03:06:40 , their wouldn't be a difference 如果OPprevious日期是2013-07-29 03:06:40 ,那么它们不会有什么不同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM