PHP 2天和48小时之间有什么区别

时间:2018-08-30 05:03:44

标签: php date

$new_date = date('Y-m-d', strtotime("+2 days"));

$new_date = date('Y-m-d', strtotime("+48 hours"));

它们相同还是不同

2 个答案:

答案 0 :(得分:2)

  

它们相同还是不同

它们是完全不同的。 客观地说,两天并不总是等于48小时

考虑越过夏令时边界。

例如,2019-04-07T02:00:00+1100(AEDT-> AEST)

$twoDays = new DateInterval('P2D');
$fortyEightHours = new DateInterval('PT48H');

$ref = new DateTimeImmutable('2019-04-07T01:00:00',
        new DateTimeZone('Australia/Melbourne'));

echo 'Reference:     ', $ref->format('r'), PHP_EOL;
echo 'Plus 2 days:   ', $ref->add($twoDays)->format('r'), PHP_EOL;
echo 'Plus 48 hours: ', $ref->add($fortyEightHours)->format('r'), PHP_EOL;

这产生

Reference:     Sun, 07 Apr 2019 01:00:00 +1100
Plus 2 days:   Tue, 09 Apr 2019 01:00:00 +1000
Plus 48 hours: Tue, 09 Apr 2019 00:00:00 +1000

注意,HHVM由于某种原因会产生不同的结果

演示〜https://3v4l.org/L4tKo

此常见的与日期/时间相关的虚假列表值得一看〜https://github.com/kdeldycke/awesome-falsehood#dates-and-time


值得指出的是,使用相同的参考日期并用strtotime()进行操作会产生与上述不同的结果。

演示〜https://3v4l.org/O6MTd

我怀疑这是因为其相对时间计算不如DateInterval那样细致。

答案 1 :(得分:0)

在语义上,它们是不同的,如Phil在另一个答案中所证明。这意味着在其他一些导致此问题的库中,差异是真实的。

但是,strtotime()的实现并未考虑到这一点,因此,以您的示例为例,它没有任何区别。

我很感兴趣是否可以通过源代码进行后续操作,所以去了:

strtotime()的实现是这样的:

  1. strtotime() starts,调用timelib_strtotime()创建初始ts构造
  2. timelib_strtotime()调用scan()来解析字符串
  3. 它会读取您提供给它的字符串,并且它得到的令牌之一是您的is considered as relativetext+2 days+48 hours
  4. 相对文本中,timelib_set_relative()被称为
  5. in timelib_set_relative()从使用using timelib_lookup_relunit()timelib_relunit_lookup array中进行查找,发现您提供了类型为TIMELIB_DAY,值1,乘数2的结构,或者结构TIMELIB_HOUR,值1,乘数24
  6. saves the information from previous call to s->time->relative construct
  7. 此构造一直传递下去,直到strtotime calls timelib_update_ts为止(并带有时区信息!)
  8. in timelib_update_ts,我们call do_adjust_relative()对此采取行动。我们不使用时区参数来做到这一点,我认为这是严重的错误
  9. do_adjust_relative() calls timelib_do_normalize()
  10. timelib_do_normalize()的小时数为do_range_limit(0, 24, 24, &time->h, &time->d),如果小时数超出硬编码限制(24),则增加天数,并减少小时数;如果do_range_limit_days()的天数则为+48 hours,如果我们超过硬编码的限制数天,则减少数天超过了限制,并考虑了跳跃时间(但没有时区!)。
  11. 返回timelib_update_ts时,我们使用时区参数call do_adjust_timezone,但是目前我们已经进行了所有调整,并且我们不知道它是使用+2 days还是{{1 }}。因此,没有区别。

TLDR:strtotime()在进行转换时不会考虑时区,因此在该函数中,即使确实如此,它也没有区别。