I am writing a calendar/scheduling app in PHP. Right now I take the day of the week you want the event to occur on and the time. I also ask for the timezone and adjust accordingly to get the event time in GMT.
Then I store that time as an offset from midnight of the day of the show. This is fine and works great, but what happens when I hit daylight savings time? I’m not sure what to do when that happens. The other problem is that not all countries have DST so I’m kind of in a bind there.
I am displaying these events on a calendar, so timing is important.
Dealing with DST is a real pain.
For future events you should store the location and the local time when the event is to occur, not the GMT time. This is because sometimes governments change when DST starts and stops (it just happened last year in the US) and the events then shift in GMT, but not in local time.
Then if you need to notify when the event is occurring, every day collect the events for the next 24-48 hrs and convert their times to GMT then. To do that, you need a location-timezone database like this one. Get the GMT offset for each location at the time of the event and use that to convert the time to GMT, then you know exactly when the event will occur.
I think you are on the right track with GMT (UTC). Use UTC as your canonical timestamp representation whenever you have some event that occurs (or has occurred) at a specific point-in-time. UTC is unaffected by DST rules, so it serves as a great, unambiguous point-in-time representation.
Once you have a strategy for unambiguous representation of the event date/time, then you can pretty easily solve the problem of localizing date/times based on what time zone makes the most sense to accept from your users (or display to them). You probably need to know and store the time zone of the event as well, but, because you’re storing the actual event date/time in UTC, you can pretty easily localize it to the time zone of the user if that is more relevant to them in any given use case.
This localization is usually performed with a time zone library either provided by your SDK (e.g. Java has java.util.Calendar) or as a third party extension (e.g. Python has pytz). I’m sure PHP has an equivalent, but I’m not as familiar with its libraries.
These libraries are usually built on top of a rules database such as the Olson Zoneinfo DB. These rules can change quite frequently, so you have to stay on top of updates to the underlying database, especially if you are developing a truly global application. However, they do a good job of externalizing the esoteric, nebulous time zone rules so that you can (in theory) update the rules database without have to perform a major upgrade of your runtime environment or make significant code changes when the DST rules in a particular area change.
It’s not the easiest problem in the world and stinks that we have to do it, but once you’ve done it a couple times and grok the separation of concerns between storing exact point-in-time representation vs. the concern of localization, then it becomes second nature.
Why not pass the responsibility to the users. I assume they need to be registered in order to use the application.
Just have them say in their profile what’s their time offset. Like GMT + 2, GMT – 8, etc. They would know when their DST settings changed and update their profile accordingly.
Of course, this depends on your user base. They may accept the approach or not.