PHP时间+1个月行为

2022-08-30 21:56:32

我知道PHP函数的不需要的行为

strtotime

例如,将月份(+1 个月)添加到日期时,例如:31.01.2011 -> 03.03.2011

我知道这不是正式的PHP错误,并且这个解决方案背后有一些论据,但至少对我来说,这种行为造成了很多时间浪费(在过去和现在),我个人讨厌它。


我发现更奇怪的是,例如:

MySQL:DATE_ADD('2011-01-31',间隔 1 个月)返回 2011-02-28 或

C# 其中新的 DateTime(2011, 01, 31).添加月份(1);将返回 28.02.2011

wolframalpha.com 给予作为投入;将于2013年2月28日星期四返回31.01.2013 + 1 month

它让我看到其他人已经找到了一个更体面的解决方案来解决我在PHP错误报告中经常看到的愚蠢问题,“如果我说我们从现在起一个月后见面,那会是哪一天”或类似的东西。答案是:如果下个月不存在31,请在该月的最后一天给我,但请坚持下个月。


所以我的问题是:有没有一个PHP函数(由某人编写)来解决这个未被官方认可的错误?因为我不认为我是唯一一个在增加/减少月份时想要另一种行为的人。

我对解决方案特别感兴趣,这些解决方案不仅适用于月底,而且完全取代了.此外,该案也应得到处理。strtotimestrotime +n months

祝您编码愉快!


答案 1

你需要的是告诉PHP要更聪明

$the_date = strtotime('31.01.2011');
echo date('r', strtotime('last day of next month', $the_date));

$the_date = strtotime('31.03.2011');
echo date('r', strtotime('last day of next month', $the_date));

假设你只在下个月的最后一天感兴趣

参考 - http://www.php.net/manual/en/datetime.formats.relative.php


答案 2

PHP开发人员肯定不认为这是错误。但是在strtotime的文档中,很少有评论可以解决您的问题(寻找2月28日的示例;)),即扩展了DateTime类

<?php
// this will give us 2010-02-28 ()
echo PHPDateTime::DateNextMonth(strftime('%F', strtotime("2010-01-31 00:00:00")), 31);
?>

类 PHPDateTime:

<?php
/**
 * IA FrameWork
 * @package: Classes & Object Oriented Programming
 * @subpackage: Date & Time Manipulation
 * @author: ItsAsh <ash at itsash dot co dot uk>
 */

final class PHPDateTime extends DateTime {

    // Public Methods
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    /**
     * Calculate time difference between two dates
     * ...
     */

    public static function TimeDifference($date1, $date2)
        $date1 = is_int($date1) ? $date1 : strtotime($date1);
        $date2 = is_int($date2) ? $date2 : strtotime($date2);

        if (($date1 !== false) && ($date2 !== false)) {
            if ($date2 >= $date1) {
                $diff = ($date2 - $date1);

                if ($days = intval((floor($diff / 86400))))
                    $diff %= 86400;
                if ($hours = intval((floor($diff / 3600))))
                    $diff %= 3600;
                if ($minutes = intval((floor($diff / 60))))
                    $diff %= 60;

                return array($days, $hours, $minutes, intval($diff));
            }
        }

        return false;
    }

    /**
     * Formatted time difference between two dates
     *
     * ...
     */

    public static function StringTimeDifference($date1, $date2) {
        $i = array();
        list($d, $h, $m, $s) = (array) self::TimeDifference($date1, $date2);

        if ($d > 0)
            $i[] = sprintf('%d Days', $d);
        if ($h > 0)
            $i[] = sprintf('%d Hours', $h);
        if (($d == 0) && ($m > 0))
            $i[] = sprintf('%d Minutes', $m);
        if (($h == 0) && ($s > 0))
            $i[] = sprintf('%d Seconds', $s);

        return count($i) ? implode(' ', $i) : 'Just Now';
    }

    /**
     * Calculate the date next month
     *
     * ...
     */

    public static function DateNextMonth($now, $date = 0) {
        $mdate = array(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
        list($y, $m, $d) = explode('-', (is_int($now) ? strftime('%F', $now) : $now));

        if ($date)
            $d = $date;

        if (++$m == 2)
            $d = (($y % 4) === 0) ? (($d <= 29) ? $d : 29) : (($d <= 28) ? $d : 28);
        else
            $d = ($d <= $mdate[$m]) ? $d : $mdate[$m];

        return strftime('%F', mktime(0, 0, 0, $m, $d, $y));
    }

}
?>

推荐