Gui*_*rmo 12 php algorithm datetime
我有一个"活动",需要在每个月的同一天安排.
假设您在5月1日设置开始日期,您应该在6月1日,7月1日等下一个事件.问题出现在31日的开始日期(下一个可能是30或28,具体取决于月份) .
考虑到有几个月有不同的天数(28,30,31),取决于月份本身和年份......什么是一个简单的方法来设置这个?
考虑以下(和有缺陷的)nextmonth函数:
$events = array()
function nextmonth($date) {
return $date+(60*60*24*30);
}
$curr = $start;
while($curr < $end) {
$events[ = $curr;
$curr = nextmonth($curr);
}
Run Code Online (Sandbox Code Playgroud)
编辑补充说:对我来说,问题是,如何解决任何给定月份的天数,从而获得下一个相应的日期.
更新:
这将为您提供给定月份的天数:
echo date('t', $timestamp);
Run Code Online (Sandbox Code Playgroud)
见:date()
老答案:
我不确定你想要的算法,但我相信这会对你有所帮助:
echo date('d-M-y', strtotime('next month'));
Run Code Online (Sandbox Code Playgroud)
在这里的所有答案中,我发现只有@ling实际上回答了这个问题,但他的答案仍然不是100%准确,它错误地输出了年份部分,正如你在他的答案中看到的那样。
这是他的代码的修改版本,修复了年份问题(我还修改了它以使用 DateTime)
因此,该解决方案还考虑了闰年,这就是为什么对于 2020 年(闰年),它显示了2020-02-29非闰年(例如 2019 年)的原因2019-02-28
/**
* Adding month in PHP using DateTime
* class will render the date in a way that
* we do not desire, for example adding one month
* to 2018-01-31 will result in 2018-03-03 but
* we want it to be 2018-02-28 instead.
*
* This method ensure that adding months
* to a date get caculated properly.
*
*
* @param DateTime $startDate
* @param int $numberOfMonthsToAdd
*
* @return DateTime
*/
function getSameDayNextMonth(DateTime $startDate, $numberOfMonthsToAdd = 1) {
$startDateDay = (int) $startDate->format('j');
$startDateMonth = (int) $startDate->format('n');
$startDateYear = (int) $startDate->format('Y');
$numberOfYearsToAdd = floor(($startDateMonth + $numberOfMonthsToAdd) / 12);
if ((($startDateMonth + $numberOfMonthsToAdd) % 12) === 0) {
$numberOfYearsToAdd--;
}
$year = $startDateYear + $numberOfYearsToAdd;
$month = ($startDateMonth + $numberOfMonthsToAdd) % 12;
if ($month === 0) {
$month = 12;
}
$month = sprintf('%02s', $month);
$numberOfDaysInMonth = (new DateTime("$year-$month-01"))->format('t');
$day = $startDateDay;
if ($startDateDay > $numberOfDaysInMonth) {
$day = $numberOfDaysInMonth;
}
$day = sprintf('%02s', $day);
return new DateTime("$year-$month-$day");
}
// Quick Test
$startDate = new DateTime('2018-01-31');
for($i=0; $i <= 40; $i++) {
echo getSameDayNextMonth($startDate, $i)->format('Y-m-d') . "\n";
}
Run Code Online (Sandbox Code Playgroud)
输出 :
2018-01-31
2018-02-28
2018-03-31
2018-04-30
2018-05-31
2018-06-30
2018-07-31
2018-08-31
2018-09-30
2018-10-31
2018-11-30
2018-12-31
2019-01-31
2019-02-28
2019-03-31
2019-04-30
2019-05-31
2019-06-30
2019-07-31
2019-08-31
2019-09-30
2019-10-31
2019-11-30
2019-12-31
2020-01-31
2020-02-29
2020-03-31
2020-04-30
2020-05-31
2020-06-30
2020-07-31
2020-08-31
2020-09-30
2020-10-31
2020-11-30
2020-12-31
2021-01-31
2021-02-28
2021-03-31
2021-04-30
2021-05-31
Run Code Online (Sandbox Code Playgroud)
由于月份的大小差异很大,设置下个月的最佳方式不是这样:今天,下个月,除非下个月不存在这一天。
例子:
June 5, 2009, next month would be July 5, 2009
August 31, 2009, next month would be September 30, 2009
Run Code Online (Sandbox Code Playgroud)
或者简单地说,strtotime("+1 month")