Managing timezones
I have gone through many timezone/PHP posts, and most suggest storing your datetime fields in UTC, then using the application users ti开发者_StackOverflow社区mezone offset when storing and displaying datetime information.
The problem i have I've inherited an application that wasn't timezone aware, and now I need to cater for this.
The server is already set to "EST +11:00 Australia/Melbourne"
, and there are already applications running from that server. So i can't change this.
Fortunately, I do know a users timezone offset, ie -05:00
, etc,.
The application takes Javascript Dates and parses them using PHP's strtotime()
function and stores in a MySQL database, like this:
$event_starts = date('Y-m-d H:i:s',
strtotime('Thu Dec 02 2010 11:15:00 GMT+1100 (AUS Eastern Daylight Time)');
So does anyone have any suggestions for the best way on how I can make this application timezone aware considering the server isn't set to UTC?
Many thanks, J.
This is not going to be very easy.
First of all, consider that existing stored dates are in local time of your server, which observes daylight saving time. Any code that has to do anything with these dates except just printing them, now or in the future, will need to convert them to UTC first. If the daylight saving rules are not exactly the same at the point in time where the date was stored and the current time (when the conversion is taking place), your server will use the "current" rules and therefore produce a wrong result. Granted, this scenario may be far-fetched in your specific case (or then again it might not), but it's a very strong warning against storing anything other than UTC.
Assuming that the DST rules remain constant, and that you have PHP >= 5.3.0, you can do this:
- Read "original" database date with
DateTime::createFromFormat
, explicitly specifying the timezone (server's TZ) - Convert to user local time with
DateTime::setTimezone
(specifying user's TZ) - Display to the user
When receiving user input, you will need to do the reverse:
- Create user local time date with with
DateTime::createFromFormat
, explicitly specifying the timezone (user's TZ) - Convert to server local time with
DateTime::setTimezone
(specifying server's TZ) - Store in database
Apart from the above, I would suggest taking your application offline at some point and convert all dates in the database to UTC. You would then be rid of the problem discussed earlier (at least in the future, as the past cannot be undone). The "server's TZ" I mention above would then be UTC (regardless of the fact that the actual server may be set to AUS EDT or not, your "working" timezone will be UTC).
You could make use of
1) date_default_timezone_set - Sets the default timezone used by all date/time functions in a script
2) Instead of using this function to set the default timezone in your script, you can also use the INI setting date.timezone to set the default timezone.
The important thing to keep in mind is not UTC, but that all times stored must be standardized to one timezone. So, if your PHP server and your database server both use the same timezone, the only issue that arises is when you need to display a location-aware time to the user or when you allow a user to enter a datetime from another timezone.
PHP has a nice, though somewhat scantly documented class, called DateTime. And some ancillary classes like DateTimeZone, DateInterval, etc. These make converting from db time to user time pretty simple.
So does anyone have any suggestions for the best way on how I can make this application timezone aware considering the server isn't set to UTC?
If you manage to come with any scheme for remapping the timezones its going to be horribly complicated and even more impossible to ever fix properly. Do yourself a favour and get the server timezone to UTC and fix your existing data.
First of allyou have to convert the date time selected by user to timestamp.
You have to use Server time zone offset and save the time to server in GMT.
This is the best way because while displaying the date just add the offset of the user
and convert and show.
I have implemented this for my client as it was an auction site and user may add item from AUS in his time and bidder will be from US. Time zone issues was there and we implemented after a lots of rerence.
You know one thing best and easy way is , do like ebay . just save the user time zone and show time with the time zone. No conversion nothing. Simple and better . 10:35 EST :)
If you wannabe perfect in time zone conversion, think about daylight saving time also. start date and end date on each year will change slightly. If you want to be accurate you have to save the daylight starting and ending date in db and add that difference too .:)
For working with datetime in different timezones and formats you can try to use PHP library Dater (https://github.com/barbushin/dater). Cheers!
精彩评论