使用strtotime获取PHP中的日期是不可预测的?

时间:2016-03-31 17:29:59

标签: php datetime

去年,这段代码一直有效。

我认为唯一改变的是闰年这一事实。我试图在网上找到类似的问题,但无法弄明白。

假设我在2016年3月30日运行。

以下是5行PHP。

echo date("F",strtotime("-4 month"));
echo date("F",strtotime("-3 month"));
echo date("F",strtotime("-2 month"));
echo date("F",strtotime("-1 month"));
echo date("F");

以下几个月回应:

December
December
January
March
March

为什么会这样? 我在http://sandbox.onlinephpfunctions.com上对它进行了大量的讨论,甚至可以看到,如果你做了-5个月,它会打印出10月。

我肯定在这个函数的操作中遗漏了一些东西。任何人都可以向我解释它/ etc的局限性吗?我想了解更多关于它不起作用的原因。

4 个答案:

答案 0 :(得分:0)

我建议您尝试以下方法:

echo date("F", strtotime("-4 month", strtotime(date("F") . "1")) );
echo date("F", strtotime("-3 month", strtotime(date("F") . "1")) );
echo date("F", strtotime("-2 month", strtotime(date("F") . "1")) );
echo date("F", strtotime("-1 month", strtotime(date("F") . "1")) );

您面临的问题归因于PHP bug

希望这有帮助。

答案 1 :(得分:0)

你可以做到这一点,我认为这很简洁:

echo date("F", strtotime('first day of -4 month'));
echo date("F", strtotime('first day of -3 month'));
echo date("F", strtotime('first day of -2 month'));
echo date("F", strtotime('first day of -1 month'));
echo date("F");

例如: https://3v4l.org/LjUCE

答案 2 :(得分:0)

来自Derick Rethans

PHP用户一遍又一遍地抱怨下个月在PHP的日期字符串解析器中没有进入下个月,而是跳到下个月之后的那个;如下例所示:

julia> filter(pair -> pair[1] + pair[2] > 7,  [(i, j) for i in l1, j in l2])
3-element Array{Tuple{Any,Any},1}:
 (3,5)
 (2,6)
 (3,6)

小脚本的输出将是March。 3月显然不会跟随1月,因为2月介于两者之间。但是,目前的行为是正确的。内部发生以下情况:

  • 下个月将月份数量(原来为1)增加一个。这个 使日期为2010-02-31。

  • 第二个月(二月)在2010年只有28天,因此PHP会自动更正这一点,只需继续计算从2月1日起的天数。然后你在3月3日结束。

  • 格式化会删除年份和日期,从而导致输出March。

使用完整日期格式回复日期时很容易看到这一点,该格式将于2010年3月3日输出:

<?php
$d = new DateTime( '2010-01-31' );
$d->modify( 'next month' );
echo $d->format( 'F' ), "\n";
?>

要获得正确的行为,您可以使用PHP 5.3的一些新功能来介绍相对时间节的第一天。此节可与下个月,第五个月或+8个月结合使用,以指定指定月份的第一天。我们使用的是下个月的第一天,而不是上一个例子的下个月:

<?php
echo $d->format( 'F jS, Y' ), "\n";
?>

此脚本将正确输出二月。当PHP处理下个月的第一天节时,会发生以下情况:

  • 下个月将月份数量(原来为1)增加一个。这个 使日期为2010-02-31。

  • 第一天将日期编号设为1,结果日期为2010-02-01。

  • 格式化会删除年份和日期,从而导致输出2月。

除了第一天,还有相当于最后一天去一个月的最后一天。以下示例演示了这一点:

<?php
$d = new DateTime( '2010-01-08' );
$d->modify( 'first day of next month' );
echo $d->format( 'F' ), "\n";
?>

此输出于2010年2月28日。内部发生以下情况:

  • 下个月将月份数量(原来为1)增加一个。这使得日期为2010-02-08。

  • 最后一天将月份数增加1,并将日期编号设为0,结果日期为2010-03-00。

  • 然后,PHP会自动更正无效的第0天,方法是从月份中删除一个并跳至该月的最后一天,从而产生2010-02-28。

我希望这可以清除PHP日期/时间处理的一些行为。

答案 3 :(得分:0)

试试这个:

for($i=5;$i>0;$i--) {
echo date("F", strtotime("-".$i." month", strtotime(date("F") . "1")) ); 
}