簡體   English   中英

PHP:DatePeriod與月的最后一天

[英]PHP: DatePeriod with last day of month

我想使用PHP DateInterval迭代幾個月:

$from = new DateTime();
$from->setDate(2014, 1, 31);

$period = new DatePeriod($from, new DateInterval('P1M'), 12);

我希望它能在2月28日1月31日返回(因為DateInterval是1個月),但實際上它將於4月31日,3月3日,4月3日返回...因此跳過2月。

有什么方法可以做到這一點嗎?

謝謝!

編輯:作為一個參考,這是一個似乎涵蓋大多數用例的解決方案:

$date = new DateTime('2014-01-31');
$start = $date->format('n');

for ($i = 0; $i < 28; $i++) {
  $current = clone $date;
  $current->modify('+'.$i.' month');

  if ($current->format('n') > ($start % 12) && $start !== 12) {
    $current->modify('last day of last month');
  }

  $start++;

  echo $current->format('Y-m-d').PHP_EOL;
}

您可以使用DateTime::modify()

$date = new DateTime('last day of january');
echo $date->format('Y-m-d').PHP_EOL;

for ($i = 1; $i < 12; $i++) {
  $date->modify('last day of next month');
  echo $date->format('Y-m-d').PHP_EOL;
}

編輯:我想我不明白你的問題。 這是一個新版本:

$date = new DateTime('2014-01-31');

for ($i = 0; $i < 12; $i++) {
  $current = clone $date;
  $current->modify('+'.$i.' month');

  if ($current->format('n') > $i + 1) {
    $current->modify('last day of last month');
  }

  echo $current->format('Y-m-d').PHP_EOL;
}

你可以嘗試這樣:

$date = new DateTime();
$lastDayOfMonth = $date->modify(
  sprintf('+%d days', $date->format('t') - $date->format('j'))
);

我會這樣做的

$max = array (
31,28,31,30,31,30,31,31,30,31,30,31
); //days in month

$month = 1;
$year = 2014;
$day = 31;

$iterate = 12;
$dates = array();
for ($i = 0;$i < $iterate;$i++) {
    $tmp_month = ($month + $i) % 12;
    $tmp_year = $year + floor($month+$i)/12;
    $tmp_day = min($day, $max[$tmp_month]);
    $tmp = new DateTime();
    $tmp->setDate($tmp_year, $tmp_month + 1, $tmp_day);
    $dates[] = $tmp;
}

var_dump($dates);

如果可能的話,每月保持一天

問題是由范圍內每個月的最后一天之間的差異引起的。 即。 2月28日結束,而不是31 ,距離最后一天2014-01-31 + 1 month = 2014-03-03 https://3v4l.org/Y42QJ

要解決這個問題DatePeriod並簡化了一點,通過重新指定的日期到指定月份的第一天,通過調整初始日期first day of this month

然后在迭代期間,您可以使用last day of this month修改日期周期日期,以檢索當前迭代月份的邊界。

示例: https//3v4l.org/889mB

$from = new DateTime('2014-01-31');
$from->modify('first day of this month'); //2014-01-01

$period = new DatePeriod($from, new DateInterval('P1M'), 12);
foreach ($period as $date) {
    echo $date->modify('last day of this month')->format('Y-m-d');
}

結果:

2014-01-31
2014-02-28
2014-03-31
2014-04-30
2014-05-31
2014-06-30
2014-07-31
2014-08-31
2014-09-30
2014-10-31
2014-11-30
2014-12-31
2015-01-31

然后展開這種方法,以便從指定日期(例如29th檢索所需的日期。 您可以提取指定的日期,並在該日超出該月的范圍時根據需要調整當前迭代的月份。

示例: https//3v4l.org/SlEJc

$from = new DateTime('2014-01-29');
$day = $from->format('j');
$from->modify('first day of this month'); //2014-01-01

$period = new DatePeriod($from, new DateInterval('P1M'), 12);
foreach ($period as $date) {
    $lastDay = clone $date;
    $lastDay->modify('last day of this month');
    $date->setDate($date->format('Y'), $date->format('n'), $day);
    if ($date > $lastDay) {
       $date = $lastDay;
    }
    echo $date->format('Y-m-d');
}

結果:

2014-01-29
2014-02-28 #notice the last day of february is used
2014-03-29
2014-04-29
2014-05-29
2014-06-29
2014-07-29
2014-08-29
2014-09-29
2014-10-29
2014-11-29
2014-12-29
2015-01-29

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM