在php中,“2天”和“48小时”有什么区别?

3

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

或者

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

他们是相同的还是不同的。

1
像这样回显 echo date('Y-m-d H:i:s', strtotime("+48 hours")); 并检查差异。 - RAUSHAN KUMAR
2
不是每一天都是24小时长的。夏令时。 - Brad
两天和48小时在现实生活中并不相同。尽管它们通常是相同的,但并没有这样的保证。话虽如此,你尝试过什么?你的结果是什么? - Ulrich Eckhardt
出于好奇:你的真正问题是什么? - Nico Haase
2
strtotime("+2 days") 将会在原日期基础上添加2天。 strtotime("+48 hours") 将会在原时间基础上添加48小时。 - Siddharth Ramani
2个回答

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。 - govind sharma
1
除了@Phil上面提到的内容,对于这种情况最好使用PHP提供的DateTime功能,而不是strtotime。 - user7193487
@eis 我喜欢学术性地考虑这样的问题。客观地说,两天并不总是等于48小时:D - Phil
正确。您可能想在答案中提到这一点,但就strtotime而言,至少似乎没有区别 :) - eis
1
我猜strtotime在其代码中只有固定的常量,这会使表达式等效,即使它们在语义上不应该这样。 - eis
显示剩余6条评论

0

从语义上讲,正如Phil在另一个答案中所示,它们是不同的。这意味着在一些其他考虑到这一点的库中,差异是真实存在的。

然而,strtotime()的实现并没有考虑到这一点,因此根据您的示例,这没有任何区别。

我很感兴趣是否可以通过源代码进行跟进,因此在这里进行了说明:

strtotime()的实现如下:

  1. strtotime()开始,调用timelib_strtotime()创建初始的ts结构
  2. timelib_strtotime()调用scan()解析字符串
  3. 它读取你提供的字符串并获取其中一个标记是+2天+48小时,这被认为是相对文本。
  4. 对于相对文本,timelib_set_relative()等函数被调用
  5. 在timelib_set_relative()中,使用timelib_lookup_relunit()进行查找,它使用{{link8:timelib_relunit_lookup数组}},发现你提供了一个类型为TIMELIB_DAY、值为1、乘数为2的构造,或者构造TIMELIB_HOUR、值为1、乘数为24
  6. 将此构造传递下去,直到strtotime 调用timelib_update_ts(和时区信息!)
  7. 在timelib_update_ts中,我们调用do_adjust_relative()来处理它。我们不使用时区参数,我认为这是关键的错误
  8. do_adjust_relative()调用timelib_do_normalize()
  9. timelib_do_normalize()对于小时执行do_range_limit(0, 24, 24, &time->h, &time->d),如果小时超过了硬编码限制24,则增加天数并减少小时,并对于天数执行do_range_limit_days(),如果超过了限制,则增加月份并减少天数,考虑闰年(但不考虑时区!)
  10. 在返回到timelib_update_ts时,我们调用do_adjust_timezone与时区参数一起,但此时我们已经进行了所有调整,我们不再知道是使用+48小时还是+2天进行的。因此没有区别。

TLDR: 在进行转换时,strtotime() 不考虑时区,因此在该函数中没有任何区别,尽管它实际上应该有所不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接