Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

datetime - PHP Daylight savings conundrum

I have a general question about dealing with daylight saving time. I guess its not really PHP specific, but I am writing in PHP, so I figure it wouldn't hurt to include it.

I have a calendar app built using jquery fullcalendar. The user views events in their local timezone and my server stores them as UTC datetimes in mysql. (Other questions on stackoverflow suggest that this is the best way to deal with timezones.) So there is a conversion every time the user saves or views events on the calendar. This is working fine, but I am confused about how best to deal with daylight saving time.

For example, say a user in timezone EST (eastern standard time) creates an event when it is NOT daylight saving for 3pm that repeats everyday. My PHP code uses the standard DateTime (and DateTimeZone) class to convert between UTC and EST by UTC-5:00. When daylight saving is active, the clock turns ahead one hour and PHP will instead convert between UTC and EST by UTC-4:00. From the user's point of view, the event is then shifted from the original 3pm to 4pm. This is not what my users and I want. A 3pm event should stay a 3pm event regardless of daylight savings. What is the best way to deal with this? Is there a way in PHP to ignore daylight saving time?

My code:

$getDate = new DateTime($storedDate, new DateTimeZone('UTC'));
$getDate->setTimezone(new DateTimeZone('America/New_York'));
$getDateString = $getDate->format('Y-m-d H:i:s');

MORE INFO: (copied from my comments below)

-Only the first occurrence of a repeating event is stored. All other occurrences are created on the fly according to what calendar view the user requests (month,week,or day views). With the way I have it coded, it creates only the occurrences that will be visible on the view.

-The thing is, I also need to keep it constant for other timezones. To continue the original example, 3pm should stay 3pm in EST (regardless of daylight savings), but if the event is viewed in Central time, the event should also stay 2pm (regardless of daylight savings).

Essentially, I need to somehow ignore daylight saving time.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Have you tried looking at DateTimeZone::getTransitions() ?

http://www.php.net/manual/en/datetimezone.gettransitions.php

In particular use the [offset] and [isdst] properties.

  • When they save the time, find the first transition before the current date that is NOT DST. (Typically one of the two values in the past year). Convert using the offset of the non-DST period
  • When retrieving the value and you are currently in a DST period use the offset of a non-DST period to translate the time, not the current offset.

Taking your EST example, in August even though you are in EDT, you save values using the EST conversion of -5.

When pulling the value back out if they view that value in January you add 5, and if you are in August you add 4.

This will work for 95% of cases I'm assuming that the switches are consistent. If Eastern decided to merge with Central, you could have transitions that run –5/–4/–5/–4/–5/–5/–6/–5/–6/–6 and that would mess things up.

There's no magic bullet for this one. I don't know the details of your app structure, you may just have to try adding 3 hours to the midnight of whatever day you are on so that any recurring daily appointment is stored as a time only.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...