请使用以下PHP代码:

<?php
$timezone = new DateTimeZone('UTC');
$startDate = new DateTime('2022-09-26T00:00:00', $timezone);
$endDate1 = new DateTime('2023-02-28T00:00:00', $timezone);
$endDate2 = new DateTime('2023-03-01T00:00:00', $timezone);
$interval1 = $endDate1->diff($startDate);
$interval2 = $endDate2->diff($startDate);
print_r($interval1);
print_r($interval2);

下面是输出结果:

DateInterval Object
(
    [y] => 0
    [m] => 5
    [d] => 2
    [h] => 0
    [i] => 0
    [s] => 0
    [f] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 1
    [days] => 155
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
DateInterval Object
(
    [y] => 0
    [m] => 5
    [d] => 5
    [h] => 0
    [i] => 0
    [s] => 0
    [f] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 1
    [days] => 156
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)

谁能解释一下,为什么第一个间隔的y-m-d0-5-2,而days计数是155,而第二个间隔的y-m-d0-5-5,即使只加了一天(实际上days的计数是156)?

我试着将相同的代码移植到其他语言中(确切地说是JavaScript和python),第一个时间间隔的结果与PHP的相同:5个月零2天. 然而,第二个间隔的结果是5个月零3天(正如我所期望的那样),而不是PHP所说的5个月零5天.

推荐答案

PHP通过简单地计算时间戳所有组成部分之间的差值来确定两个日期之间的差值.(年、月、天等(ref))所以第二个间隔在这个阶段看起来像(y=1, m=-6, d=-25).然而,这对我们人类来说没有什么意义,所以PHP试图通过调整每个字段来正常化这个间隔,如果下一个字段上溢或下溢.(ref).但是月份并不包含一致的天数,所以PHP试图变得聪明一些,根据我们开始的月份的长度逐日进行调整.(ref)

因此,如果第一个日期在2月份,天数字段将调整28天:(y=1, m=-7, d=2),而3月份有31天,结果为(y=1, m=-7, d=5).这两个间隔的下一步是月份调整,这是相同的.一年有12个月,所以我们得到(y=0, m=5, d=2)(y=0, m=5, d=5).


了解了这一点,我们可以更多地享受PHP变得奇怪的乐趣

$start = new DateTime('2022-09-26');
$end = new DateTime('2023-03-01');

$start->diff($end); // +5m 3d
$end->diff($start); // -5m 5d

EDIT:我关于PHP内部如何工作的第一个假设被证明是错误的,所以在@Kiko Software提出他们的问题后,上面的答案被重写了.

Php相关问答推荐

如果活动订阅者的购物车中有订阅项目,则在WooCommerce签出中显示通知

将产品类别添加到WooCommerce产品附加信息

在特定订单状态更改时自定义WooCommerce订单发货项目

Symfony 6.2 IsGraned具有多个角色

使用随机生成器在MYSQL中创建唯一ID-定义一个数组来存储已知ID是否安全

向WooCommerce管理订单总额添加自定义总额行

HTTPPost请求在从php脚本调用时返回404,但在从node.js脚本调用时有效.终结点有效

ANTLR4-lexer如何消耗更多的 token 并停止现有规则?

防止在WordPress短代码中显示重复产品并请求代码更正

将自定义字段添加到管理产品中 WooCommerce 3.2+ 中的快速编辑

使用 wp_footer 挂钩添加一些 CSS 不起作用

在特征中使用类的属性

为WooCommerce中的Guest用户保存唯一的客户代码到订单中

基于WooCommerce中的产品变体自定义感谢页面跳转

用于检测此模式的正则表达式:something;something=something,something=something... 未知次数

如何用 php ML 解决这个问题?

在 Laravel、Vuejs 和 Inertia 中配置 TypeScript 的问题

如何在不解压缩/重新压缩的情况下连接(连接)两个缩小的值

PHP Remedy API 调用以创建附件无效的条目(使用 Postman Works!)

在管理表单字段中