Php 从一个日期中减去整整一个月
如果您需要可靠和准确的日期操作,那么似乎无法使用Php 从一个日期中减去整整一个月,php,datetime,strtotime,Php,Datetime,Strtotime,如果您需要可靠和准确的日期操作,那么似乎无法使用strotime。例如,如果一个月有31天,那么strotime似乎只是减去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 问题:现在我怎么知道怎么不做,有没有另一种更
strotime
。例如,如果一个月有31天,那么strotime
似乎只是减去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天?主要问题是不存在
2013/09/31
,因此更好的方法是使用上个月的第一天
或最后一天
$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
你说:-
如果您需要可靠和准确的日期操作,那么您似乎无法使用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可以正确计算月份减法
在您的特殊情况下,2013年10月31日-1个月是2013年9月31日,该日期不存在。任何日期/时间函数都需要返回有效日期,而2013-09-31不是
在本例中,正如我前面所述,PHP似乎比上个月的开始时间多了31天,以获得一个有效日期
一旦知道预期的行为,就可以相应地编程。如果当前行为不适合您的用例,那么您可以扩展DateTime类以提供适合您的行为
我假设strotime和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);
}
如果你正在处理带有日期和时间的事件,那么就让自己的生活更轻松,并使用DateTime对象。我认为真正的问题是,它从10月31日减去一个月,返回9月31日,而9月31日并不存在,而是转换为10月1日。“如果我在10月29日获取你的代码并输入它,我会像预期的那样得到9月29日。”Blazemonger说,这将被严重破坏。我不敢相信strotime()(它实际上不是PHP的一部分,它是一个底层的通用C库)有这样的缺陷,因为2013/09/31不存在,问问你自己你希望返回什么。显然,任何语言的日期/时间函数都不能接受9月31日。在这种情况下,我认为你不能说9月30日比10月1日更正确。重要的是,这种行为是一致的和可预测的,我相信是的,尽管我还没有测试过它,尽管我可能会在有时间的时候做,因为这激发了我的好奇心。如果日期是2013-10-15,那就不好了——但我现在看到了这个问题。该死<代码>日期时间非常灵活。。我会更新我的代码,以显示如何实现这一点。。。
$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);
}