0

find some problem when i was try to count days between two dates.
For fast debug my code i use http://sandbox.onlinephpfunctions.com/ with PHP version 7.4.0

Problem:

$date = new DateTime( '2018-02-28' );
$date2 = new DateTime( '2018-03-12' );
$diff = $date2->getTimestamp() - $date->getTimestamp();
var_dump($diff/(60*60*24)); //float(11.958333333333)

As you see - i set dates and calculated unixtimestamp-diff between dates.
Then i try find date when diff between two dates != 86400.

$date = new DateTime( '2020-03-08' );
$date2 = new DateTime( '2020-03-09' );
$diff = $date2->getTimestamp() - $date->getTimestamp();
var_dump($diff/(60*60*24)); //float(0.95833333333333)

Then i find all days from 2010 year:

$secInDay = 60 * 60 * 24;
$start_date = strtotime('2010-01-01');
$end_date = strtotime('2021-01-01');

while($start_date<$end_date) {
    $next_date = strtotime('+1 day', $start_date);
    $diff = ($next_date - $start_date) / $secInDay;
    if ($diff !== 1) {
        var_dump(date('d.m.Y', $start_date) . ' -> ' . date('d.m.Y', $next_date));
    }
    $start_date = strtotime('+1 day', $start_date);
}

Result:
string(24) "14.03.2010 -> 15.03.2010"
string(24) "07.11.2010 -> 08.11.2010"
string(24) "13.03.2011 -> 14.03.2011"
string(24) "06.11.2011 -> 07.11.2011"
string(24) "11.03.2012 -> 12.03.2012"
string(24) "04.11.2012 -> 05.11.2012"
string(24) "10.03.2013 -> 11.03.2013"
string(24) "03.11.2013 -> 04.11.2013"
string(24) "09.03.2014 -> 10.03.2014"
string(24) "02.11.2014 -> 03.11.2014"
string(24) "08.03.2015 -> 09.03.2015"
string(24) "01.11.2015 -> 02.11.2015"
string(24) "13.03.2016 -> 14.03.2016"
string(24) "06.11.2016 -> 07.11.2016"
string(24) "12.03.2017 -> 13.03.2017"
string(24) "05.11.2017 -> 06.11.2017"
string(24) "11.03.2018 -> 12.03.2018"
string(24) "04.11.2018 -> 05.11.2018"
string(24) "10.03.2019 -> 11.03.2019"
string(24) "03.11.2019 -> 04.11.2019"
string(24) "08.03.2020 -> 09.03.2020"
string(24) "01.11.2020 -> 02.11.2020"

So my main question - why PHP get wrong unix-timestamp for current dates?

3
  • 1
    This year is a Leap Year Commented Feb 28, 2020 at 11:07
  • Your algorithm finds the days for the changeover from winter/summer time and summer/winter time for the current time zone. These days have 23 or 25 hours. Commented Feb 28, 2020 at 11:16
  • Please highlight which exact results are not calculated as expected, and explain the difference. Also explain which timezone you use Commented Feb 28, 2020 at 11:26

3 Answers 3

1

Your algorithm finds the days for the changeover from winter/summer time and summer/winter time for the current time zone. These days have not 24 hours.

Russia no longer knows summer time. With

date_default_timezone_set('Europe/Moscow');

in the first line you get the result for your region. Try it self.

Update:

You get correct results with DateTime-Objects:

date_default_timezone_set('Europe/Moscow');

$diff = date_create('28.03.2010')->diff(date_create('29.03.2010'))->days;
echo $diff;  //1
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Don't think about winter/summer time!
0

You can change the default UTC with this function:

date_default_timezone_set('America/Los_Angeles');

https://www.php.net/manual/en/function.date-default-timezone-set.php


Or directly edit your INI configuration file from your web server. https://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone

1 Comment

Editing the INI configuration is not a good idea: If 2 authors need 2 different time zones for 2 different websites at the same server, and both are edit the INI file, then one website doesn't work like expected. Using date_default_timezone_set() at a central place of the website (e.g. standard library) is clearly the better choice.
0

If you use the DateTime class like this and calculate the interval the leap year is catered for

function days_between( $start, $end )
{
    // Put the 2 dates into DateTime objects
    $start = new DateTime($start);
    $end  = new DateTime($end);
    // Create a DateInterval object using diff() method
    $interval = $end->diff($start);
    // Format the result as an integer, representing number of days
    return $interval->format('%a');
}

#not leap year
echo days_between('2019-02-27', '2019-02-27') . PHP_EOL;    // 0
echo days_between('2019-02-27', '2019-02-28') . PHP_EOL;    // 1
echo days_between('2019-02-27', '2019-02-29') . PHP_EOL;    // 2 (there is no 29th
echo days_between('2019-02-27', '2019-03-01') . PHP_EOL;    // 2
echo PHP_EOL;

#Leap Year
echo days_between('2020-02-27', '2020-02-27') . PHP_EOL;    // 0
echo days_between('2020-02-27', '2020-02-28') . PHP_EOL;    // 1
echo days_between('2020-02-27', '2020-02-29') . PHP_EOL;    // 2
echo days_between('2020-02-27', '2020-03-01') . PHP_EOL;    // 3

RESULT

0
1
2
2

0
1
2
3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.