PHP - date()减少错误?

时间:2009-09-15 09:07:13

标签: php date

我使用unix时间戳作为我在日期范围查询中使用的开始日期的基础。开始日期不是问题,为了本例的目的,我将使用以下时间戳:1228089600(2008年12月1日00:00:00)。

要在我的查询中使用,我需要轻松找出任何一个月的最后一天到最后一秒所以..

date('o-m-d G:i:s',mktime(0, 0, -1, date("m",1228089600)+1, 1, date("o",1228089600)));

除了12月之外,这个方法对我来说每隔一个月工作正常。通过开始日期,加上整月(2009年1月1日00:00:00)然后拿走1秒我期待结果我需要的日期(2008年12月31日23:59:59)。然而,看起来这一年的额外月份是正确计算的,但是因为返回日期是2009年12月31日23:59:59而没有减去第二年。

正如我所说,这种方法很有效,直到我发现了这个问题。但这是一个问题,我无法弄清楚原因或简单的解决方案..

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

这是因为:

  

flag'o' - ISO-8601年号。这有   与Y相同的值,除非是   ISO周号(W)属于   那一年或明年,那一年是   用来代替。 (在PHP 5.1.0中添加)

所以在你的情况下发生这个:

  1. 生成日期为2009年1月1日
  2. 日期减少1秒(因此您将获得2008年12月31日)
  3. 但正如上面所描述的那样 - 本周属于2009年,因此返回2009而不是2008
  4. (属于年份意味着:2009年比2008年更多的日子 - 在上述情况中:3天是在2008年(星期一,星期二,星期三,29日,30日,31日),4日是在2009年(星期四,星期五,坐着,太阳 - 第1,第2,第3,第4))

答案 1 :(得分:1)

这似乎确实是mktime()如何处理大于12的“月”值的错误。

php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 2, 1, 2008));
2008-01-31 23:59:59
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 3, 1, 2008));
2008-02-28 23:59:59
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 1, 1, 2008));
2007-12-31 23:59:59

php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 13, 1, 2008));
2009-12-31 23:59:59
php > echo date('o-m-d G:i:s',mktime(0, 0, -1, 13, 1, 2007));
2008-12-31 23:59:59

你现在最好的选择可能只是自己查看date('m', ...)+1的输出,如果结果为13则可以计算特殊情况。

答案 2 :(得分:1)

如果月份是1月份,我确实添加了一些例外以减少年份,但是我还有另一个日期范围,它与GA api一起使用。尽管方法相似,但我很惊讶地看到这个日期范围很好。不同之处在于......

有问题:

date('o-m-d G:i:s',mktime(0, 0, -1, date("m",1228089600)+1, 1, date("o",1228089600)));

精细:

date('Y-m-d G:i:s',mktime(0, 0, -1, date("m",1228089600)+1, 1, date("Y",1228089600)));

因此,切换似乎已解决了问题。

希望有一天这一切对某人有用。

答案 3 :(得分:0)

试试这个:

$start = 1228089600;
$number_of_days_in_month = date('t', $time);
$end = strtotime('+' . $number_of_days_in_month . ' days', $start) - 1;
// subtract one second to get 23:59:59 or don't to get 00:00:00.
// Also note that there can be a leap second.
// $end = $start + $number_of_days_in_month * 86400 - 1; would probably work as well.

echo date('o-m-d G:i:s', $end);