如果您需要可靠和准确的日期操作,似乎无法使用strotime
。例如,如果月份有31天,那么strtotime
似乎只会缩短30天,而不是整整一个月。
因此,例如,如果$event["EndDate"]
等于“2013-10-31 00:00:01”,则代码如下:
echo date("Y/n/j", strtotime('-1 month', strtotime($event["EndDate"]));
输出:2013/10/1
而不是2013/09/30
。
问题:现在我怎么知道怎么不这样做,是否有另一种更准确的方法让PHP减去(或添加)整整一个月,而不仅仅是30天? / p>
答案 0 :(得分:2)
主要问题是2013/09/31
不存在,因此更好的方法是使用上个月的first day
或last day
。
$date = new DateTime("2013-10-31 00:00:01");
$date->modify("last day last month");
echo $date->format("Y/n/j"); // 2013/9/30
日期为2013-10-15
$date = new DateTime("2013-10-15 00:00:01");
$day = $date->format("d");
$year = $date->format("Y");
$date->modify("last day last month");
$month = $date->format("m");
if (checkdate($month, $day, $year)) {
$date->setDate($year, $month, $day);
}
echo $date->format("Y/n/j"); // 2013-9-15
答案 1 :(得分:1)
你说: -
如果你需要可靠和准确的日期操作,似乎你不能使用strotime
你可以,你只需要知道它的行为方式。你的问题促使我进行了几项测试。
PHP不仅仅减去了减去一个月的日期30天,尽管看起来它只是你正在查看的单个案例。事实上,我的测试here表明它在上个月开始时增加了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可以正确计算月减法here。
$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个月是2013-09-31,不存在。任何日期/时间函数都需要返回一个有效的日期,而不是2013-09-31。
在这种情况下,如上所述,PHP似乎在上个月开始时增加了31天才能到达有效日期。
一旦了解了预期的行为,就可以进行相应的编程。如果当前行为不适合您的用例,那么您可以扩展DateTime类以提供适合您的行为。
我认为strtotime
和DateTime::sub()
的行为相同,this test表明他们的行为相同。
$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);
}