简体   繁体   中英

Missing Date in DatePeriod Object

I have following script. I create a starting datetime object and an end datetime object. Then i create a dateperiod object with a 1 month date interval. The i simply iterate through all dates.

My problem is, as you can see the output below, the iteration is missing 2015-04-01 00:00:00.000000 .

Is something wrong with my script or is it a bug?

PS: Changing the DateTimeZone doesnt change the output.

$start = \DateTime::createFromFormat('d.m.Y', '31.03.2015')->setTime(0, 0);
$end = \DateTime::createFromFormat('d.m.Y', '10.02.2016')->setTime(0, 0);

$datePeriod = new \DatePeriod($start, new \DateInterval('P1M'), $end);

var_dump($start, $end);
foreach ($datePeriod as $date) {
    var_dump($date);
}

Output of var_dump($start, $end);

object(DateTime)[1524]
  public 'date' => string '2015-03-31 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1477]
  public 'date' => string '2016-02-10 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)

Output of foreach() var_dump($date);

object(DateTime)[1581]
  public 'date' => string '2015-03-31 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1438]
  public 'date' => string '2015-05-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1581]
  public 'date' => string '2015-06-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1438]
  public 'date' => string '2015-07-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1581]
  public 'date' => string '2015-08-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1438]
  public 'date' => string '2015-09-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1581]
  public 'date' => string '2015-10-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1438]
  public 'date' => string '2015-11-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1581]
  public 'date' => string '2015-12-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1438]
  public 'date' => string '2016-01-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)
object(DateTime)[1581]
  public 'date' => string '2016-02-01 00:00:00.000000' (length=26)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)

To clarify you want to just loop through every day between two date ranges? If so you can approach the problem differently.

$startDate = \DateTime::createFromFormat('d.m.Y', '31.03.2015');
$endDate   = \DateTime::createFromFormat('d.m.Y', '10.02.2016');

while ($startDate <= $endDate) {
    // Logic here.

    $startDate->modify('+1 day');
}

The above will loop through all days between the two dates by a day increment, this should suffice for now if your requirement is what I think it is?

Also you could just initialise the DateTime objects to whatever start/end date you require then loop through as shown above, you can increment by whatever value you need +1 day , +1 week and so on.

Just a bit of additional information for handling DateTime

If you want to loop through the first day of a month, to the last day of the month then it would be easier to use something like:

$date      = new DateTime();
$startDate = DateTime::createFromFormat('Y-m-d H:i:s', $date->format('Y-m-01 00:00:00');
$endDate   = DateTime::createFromFormat('Y-m-d H:i:s', $date->format('Y-m-t 00:00:00');

t gets you the last day of a month,

01 gets you the first day of the month

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM