你说:-
如果您需要可靠且准确的日期操作,您似乎无法使用 strotime
你可以,你只需要知道它的行为方式。您的问题促使我进行了几次测试。
PHP 不只是在减去一个月时从日期中减去 30 天,尽管它似乎是从您正在查看的单个案例中得出的。事实上,我在这里的测试表明,在这种情况下,它比上个月的开始增加了 31 天(3 月 3 日的结果向我表明了这一点)。
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$oneMonth = new \DateInterval('P1M');
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = new \DateTime("2013-{$month}-31 00:00:01");
var_dump($date->format($format));
$date->sub($oneMonth);
var_dump($date->format($format));
}
2013-11-12 和 2013-10-12 之间有 31 天,PHP 可以正确计算月份减法,如下所示。
$date = new \DateTime('2013-11-12 00:00:01');
var_dump($date);
$interval = new DateInterval('P1M');
$date->sub($interval);
var_dump($date);
在您的特定情况下 2013-10-31 - 1 month 是 2013-09-31 ,它不存在。任何日期/时间函数都需要返回有效日期,而 2013-09-31 则不是。
在这种情况下,正如我上面所说的,PHP 似乎在上个月的开始时间增加了 31 天才能到达有效日期。
一旦你知道了预期的行为,你就可以进行相应的编程。如果当前行为不适合您的用例,那么您可以扩展 DateTime 类以提供适合您的行为。
我已经假设strtotime
并且DateTime::sub()
行为相同,这个测试表明他们这样做。
$thirtyOnedayMonths = array(
1, 3, 5, 7, 8, 10, 12
);
$format = 'Y-m-d';
foreach($thirtyOnedayMonths as $month){
$date = date($format, strtotime('-1 month', strtotime("2013-{$month}-31 00:00:01")));
var_dump($date);
}