从日期中删除一个月

时间:2013-05-08 17:17:28

标签: php datetime strtotime

如果您需要可靠和准确的日期操作,似乎无法使用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>

2 个答案:

答案 0 :(得分:2)

主要问题是2013/09/31不存在,因此更好的方法是使用上个月的first daylast 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类以提供适合您的行为。

我认为strtotimeDateTime::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);
}