简体   繁体   中英

Adding 1 day to timestamp in PHP

I have a web app that stores all dates as UTC time stamps. Dates are changed for display purposes for the clients using a timezone setting. However, I've hit an edge case last Sunday (2 November 2014) which is when DST ended in the USA. I thought my code handled the case because it uses strtotime and "+1 Day" but it doesn't. Here the code that I've got:

$current_date_start=$this->date_start; //$this->date_start is a UTC timestamp
$current_date_end=strtotime('+1 day', $current_date_start);
do
{
    $current_date_start=strtotime('+1 day', $current_date_start);
    $current_date_end=strtotime('+1 day', $current_date_start); 
    echo format_local_date($current_date_start,'America/Los_Angeles',"D F j Y H i s")."<br />";
}
while ($current_date_start<$this->date_end);    


function format_local_date($timestamp,$timezone,$format_str='')
{
    $date_time=new DateTime_52("now",new DateTimeZone($timezone));
    $date_time->setTimestamp($timestamp);
    if ($format_str=='')
        $format_str="F j Y";
    return $date_time->format($format_str);
}

//
//DateTime_52 class
//

/**
 * Provides backwards support for php 5.2's lack of setTimestamp and getTimestamp
 */
class DateTime_52 extends DateTime{
    /**
     * Set the time of the datetime object by a unix timestamp
     * @param int $unixtimestamp
     * @return DateTime_52
     */
    public function setTimestamp($unixtimestamp){
        if(!is_numeric($unixtimestamp) && !is_null($unixtimestamp)){
            trigger_error('DateTime::setTimestamp() expects parameter 1 to be long, '.gettype($unixtimestamp).' given', E_USER_WARNING);
        } else {
            $default_timezone=date_default_timezone_get();
            $this_timezone= $this->getTimezone();
            date_default_timezone_set($this->getTimezone()->getName());
            $this->setDate(date('Y', $unixtimestamp), date('n', $unixtimestamp), date('d', $unixtimestamp));
            $this->setTime(date('G', $unixtimestamp), date('i', $unixtimestamp), date('s', $unixtimestamp));
            date_default_timezone_set($default_timezone);
        }
        return $this;
    }
    /**
     * Get the time of the datetime object as a unix timestamp
     * @return int a unix timestamp representing the time in the datetime object
     */
    public function getTimestamp(){
        return $this->format('U');
    }
}

And here's the output:

Sun November 2 2014 00 00 00
Sun November 2 2014 23 00 00
Mon November 3 2014 23 00 00
Tue November 4 2014 23 00 00
Wed November 5 2014 23 00 00
Thu November 6 2014 23 00 00
Fri November 7 2014 23 00 00
Sat November 8 2014 23 00 00

As you can see it's dropped an hour. Clearly a DST edge case. But I thought the "+1 Day" should handle that. HELP!

Your order of operations is wrong. You're adding the +1 day to the UTC time, which doesn't have the DST variance. You should convert to the local timezone first, and THEN add your +1 day, and that'll do the trick, since the calculation will be within the correct timezone to do that check automatically as expected.

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