简体   繁体   中英

PHP date time conversion issues related to daylight savings

I have some localisation functions within my webapp (exposed via Ajax) which enable users to display some datetime information in their own timezone as well as the timezone relating to the location of the entity the data primarily relates to.

As a result of some testing, I've discovered that whilst my code is capable of converting DB sourced date/time values accurately (ie including DST adjustments), the code would not calculate the correct offsets when I was using dates provided within a form. The best I've been able to achieve is converting the form date/time value to UTC but the incorrect offset is applied. This means that I need to check whether the date falls within the daylight savings range and if so, pull the datetime value back by an hour. This seems like an ugly fix and I'd appreciate it if anyone knows where I've gone wrong:

Example:

  • Input value of 25/11/2018 16:00 NZDT (Pacific/Auckland) = UTC+13
  • Output value should be 25/11/2018 14:00 ADT (Australia/Sydney) = UTC+11
  • If I extract the source value from the Database and then convert then the calculations work fine, no issues
  • If I use a form provided value (which I need to check for in case the user has updated the value without saving it), then the following occurs:

  • FROM DB1 = 2018-11-25 03:00:00 (value in the DB, in UTC)

  • FROM FORM1 = 25/11/2018 16:00 (raw value from the form)
  • FROM FORM2 = 2018-11-25 04:00:00 (changes to UTC-12, ie NZST) which is wrong, should be the same value as DB1, ie UTC-13 which is the offset from NZDT back to UTC)
  • FROM FORM3 = 2018-11-25 03:00:00 (corrected, once I check whether date/time value falls within a daylight savings range)

Code follows:

echo "FROM DB1:  ".$getListing['lo_deadline']."<BR />";
echo "FROM FORM1:".$in_lo_deadline."<BR />";
$frmDateTime =  DateTime::createFromFormat($this->view->user->user_datetimeformat, $in_lo_deadline,new DateTimeZone($list_tmzn));                   
echo "FROM FORM2:".$frmDateTime->format('Y-m-d h:i:s')."<BR />";
//If $frmDateTime is in daylight savings then subtract an hour to arrive at the correct UTC value                   
if ($frmDateTime->format('I'))
{
    date_sub($frmDateTime, date_interval_create_from_date_string('1 hours'));
}
echo "FROM FORM3:".$frmDateTime->format('Y-m-d h:i:s')."<BR />";                    
$dates['set_dead'] = convertUserDate($frmDateTime->format('Y-m-d h:i:s'), $this->view->user->user_datetimeformat, $user_tmzn,'UTC');

What I understand from your code, the reason why it's showing 2018-11-25 04:00:00 is because of AM/PM format. You should be using capital H instead of h in your code.

You need to understand the difference between 24 hour and 12 hour formats. 2018-11-25 04:00:00 according to your format is in AM/PM or 12 hour format, but in 24 hour format it should be 2018-11-25 16:00:00 . Database time is always in 24 hour format.

Change

$frmDateTime->format('Y-m-d h:i:s')

to

$frmDateTime->format('Y-m-d H:i:s')

Note: You don't need to manually subtract an hour to calculate daylight saving time as php does it automatically.

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