PHP strtotime() function wrong by 1 hour?

15,756

Solution 1

Europe/London time is not GMT time during Daylight Savings. You need to set it to UTC.

date_default_timezone_set('UTC');

date_default_timezone_set('GMT'); may work, but, as Kenneth notes in a comment below, it is deprecated.

Solution 2

London time zone is expressed in British Summer Time during Summer. Having said that, it's a good practice to store time in UTC and present the time to end user in either UTC or in THEIR local time.

It is also probably wise to ensure that your system time is UTC.

Share:
15,756
Admin
Author by

Admin

Updated on June 05, 2022

Comments

  • Admin
    Admin about 2 years

    I am converting dates and times into timestamps using PHP before they are inserted into my MySQL database.

    My problem is that when i use PHP's strtotime function the output timestamp is -1 hour behind my actual time.

    For example, considering todays date: 07/21/2010. When i use php code like:

    <?php
    $my_timestamp = strtotime("07/21/2010");
    echo $my_timestamp;
    ?>
    

    The timestamp sent back is the GMT equivilent MINUS 1 hour. i.e. i get back: 20 Jul 2010 23:00:00 GMT instead of 21 Jul 2010 00:00:00 GMT.

    I live in the UK so my timezone is GMT. I have declared my timezone in the script using date_default_timezone_set('Europe/London') and i have also ensured that the php.ini file is set to 'Europe/London'.

    Is this something to do with daylight savings time perhaps? How can i fix the problem without adding 1 hour to all my dates?

  • Daniel Egeberg
    Daniel Egeberg almost 14 years
    Sure it isn't your understanding the PHP's date and time functions that is "bugged"?
  • Gleiemeister 2000
    Gleiemeister 2000 almost 14 years
    <?php echo date( "Y-m-d", strtotime( "2009-01-31 +1 months" ) )."<br>"; ?> Try that one.
  • Yahel
    Yahel almost 14 years
    @Android Noob I'm not sure I'd want that to work. 1 month is not a fixed unit of measurement. It could be 28, 29, 30 or 31 days depending on the month, unlike the other strtotime() interpretations that do work (+1 day, +1 week), which are always a fixed quantity of time, regardless of when they occur. (That said, I'm not one of your down-voters).
  • Gleiemeister 2000
    Gleiemeister 2000 almost 14 years
    well the same thing can happen if you add or deduct an amount of days - which should only work one way. If you pass certain thresholds it will return a wrong date. If thats not bugged tell me what is.
  • Daniel Egeberg
    Daniel Egeberg almost 14 years
    So it is as I expected. +1 month simply increases the month part with 1. Because 2009-02-31 doesn't exist it overflows to 03. This is consistent with the GNU specifications. You can use first day of next month or last day of next month.
  • NullUserException
    NullUserException almost 14 years
    @yc That's because 2008 is a leap year. So 2008-02-31 overflows to 2008-03-02 instead.
  • Daniel Egeberg
    Daniel Egeberg almost 14 years
    @yc: That's just because 2008 was a leap year and so February had 29 days. 2009-02-31, that's three too many days in Feb, so it goes to Mar 3. 2008-02-31, that's two too many days in Feb, so it goes to Mar 2. You can try yourself with 2010-02-28 +1 month, this will become 2010-03-28 as expected because it just bumps up the month part.
  • Yahel
    Yahel almost 14 years
    @Daniel Egeberg then why does 2010-06-31 + 1 month get me August 1, but 2010-06-28 + 1 month get me July 28? This is pretty screwy.
  • NullUserException
    NullUserException almost 14 years
    @yc It's not "screwy" at all. June doesn't have 31 days.
  • Yahel
    Yahel almost 14 years
    @NullUserException ...I should go home now. In my time zone, I should have left work an hour ago. Clearly my brain is fried. You guys are right; I'm wrong. Oops.
  • Daniel Egeberg
    Daniel Egeberg almost 14 years
    @yc Because 2010-06-31 doesn't exist, so it overflows to 2010-07-01. Then you add one month and get 2010-08-01.
  • Gleiemeister 2000
    Gleiemeister 2000 almost 14 years
    Well we can disagree about whats a requirement for a bug but: Reproduce code: --------------- <? $t=strtotime("January 1, 2008"); echo date("c\n", strtotime("+1 Month",$t)); $t=strtotime("January 29, 2008"); echo date("c\n", strtotime("+1 Month",$t)); $t=strtotime("January 31, 2008"); echo date("c\n", strtotime("+1 Month",$t)); $t=strtotime("February 29, 2008"); echo date("c\n", strtotime("+1 Month",$t)); ?> produces: 2008-02-01T00:00:00-08:00 2008-02-29T00:00:00-08:00 2008-03-02T00:00:00-08:00 2008-03-29T00:00:00-07:00 Thats why they in php 5.3 changed it so you were able to calculate right
  • Daniel Egeberg
    Daniel Egeberg almost 14 years
    @Android Noob: Dunno what you're talking about. That script has the exact same (correct!) output in both PHP 5.2 and PHP 5.3. Feel free to submit it as a bug to bugs.php.net, but I guarantee that it will be closed as bogus.
  • NullUserException
    NullUserException almost 14 years
    @Android: Which is exactly what you'd expect it to produce. The rationale behind the generated dates has been throughly explained by Daniel Egeberg. What is the problem?
  • Gleiemeister 2000
    Gleiemeister 2000 almost 14 years
    both of you could start reading the changelog right here: php.net/manual/en/function.strtotime.php several bugs are explained corrected there. Then secondly the 'last day of next month' was implemented because the function was inconsistent. Consistency is important in calculating dates afaik.
  • NullUserException
    NullUserException almost 14 years
    @Android How is it "not consistent?" +1 month adds 1 month to the month part of the date. If that date does not exist, it overflows. It's being doing this consistently since the function was created. Just because it doesn't fit your concept idea of what it should do, it doesn't mean it's "bugged." The function behaves consistently and correctly. In fact, Jan-31 + 1 month = Mar 2nd makes total sense. What did you expect it to do?
  • NullUserException
    NullUserException almost 14 years
    Consistent: con·sist·ent/kənˈsistənt/Adjective 1. (of a person, behavior, or process) Unchanging in achievement or effect over a period of time.
  • Gleiemeister 2000
    Gleiemeister 2000 almost 14 years
    I can see your point, still think it should overflow because its already not a fixed amount if you add a month. Also I found the bug we suffered from in the changelog "In PHP 5 prior to 5.2.7, requesting a given occurrence of a given weekday in a month where that weekday was the first day of the month would incorrectly add one week to the returned timestamp. This has been corrected in 5.2.7 and later versions."
  • Kenneth
    Kenneth over 12 years
    CAUTION: GMT has since been depreciated in more recent versions of PHP and while it is still being supported temporarily, it is strongly recommended that UTC is used instead.
  • Yahel
    Yahel over 12 years
    @Kenneth Added a note. Thanks!