David
David

Reputation: 17

PHP strtotime is missing a day during leap year

I'm trying to generate a list of consecutive date periods by using strtotime to add 13 days to the first date like this:

$start = strtotime(date('2020-06-01'));

for($x = 1; $x<=10; $x++) // increment $x until 10
{
    $period     = $start - ($x * 1209600); // 1209600 is equivalent to 14 days. Multiply by $x
    $period_end = date('Y-m-d', strtotime(date('Y-m-d', $period). ' + 13 days'));
    echo date('Y-m-d', $period) . " - " . $period_end ."<br>";
}

The output looks like this:

2020-05-18 - 20-05-31
2020-05-04 - 20-05-17
2020-04-20 - 20-05-03
2020-04-06 - 20-04-19
2020-03-23 - 20-04-05
2020-03-09 - 20-03-22
2020-02-23 - 20-03-07
2020-02-09 - 20-02-22
2020-01-26 - 20-02-08
2020-01-12 - 20-01-25

Everything works as expected until it hits the '2020-02-23 - 20-03-07' range. It should report '2020-02-24 - 2020-03-08' Why the shift by 1 day? Is this a bug in PHP strtotime in relation to a leap year?

Edit: This was not a leap year issue. It turned out to be a daylight savings time issue in my timezone. When DST occurred on 3/8 the time in seconds from epoch changed by an hour. This shifted my date to 1 hour earlier which ends up being a previous day.

Upvotes: 0

Views: 442

Answers (1)

Andreas
Andreas

Reputation: 23958

If we add H:i to your date()'s it all becomes clear.

$start = strtotime(date('2020-06-01'));

for($x = 1; $x<=10; $x++) // increment $x until 10
{
    $period     = $start - ($x * 1209600); // 1209600 is equivalent to 14 days. Multiply by $x
    $period_end = date('Y-m-d H:i', strtotime(date('Y-m-d H:i', $period). ' + 13 days'));
    echo date('Y-m-d H:i', $period) . " - " . $period_end ."<br>\n";
}

Output:

2020-05-18 00:00 - 2020-05-31 00:00<br>
2020-05-04 00:00 - 2020-05-17 00:00<br>
2020-04-20 00:00 - 2020-05-03 00:00<br>
2020-04-06 00:00 - 2020-04-19 00:00<br>
2020-03-22 23:00 - 2020-04-04 23:00<br>
2020-03-08 23:00 - 2020-03-21 23:00<br>
2020-02-23 23:00 - 2020-03-07 23:00<br>
2020-02-09 23:00 - 2020-02-22 23:00<br>
2020-01-26 23:00 - 2020-02-08 23:00<br>
2020-01-12 23:00 - 2020-01-25 23:00<br>

r3mainer comment is correct. Add 12:00 to the start and the problem will go away.
Because of the daylight savings you remove one hour too much, it's not the leap year.

$start = strtotime(date('2020-06-01 12:00'));

https://3v4l.org/Uj2CA

Upvotes: 2

Related Questions