I need some guidance with one of my project requirements, I am developing an application which has to deal with various time zones.
Scenario:
User 1 is from India, so his time zone would be GMT+05:30
User 2 is from UK, so his time zone would be GMT+01:00
If the User 1 sends a message to User 2, I want to show the Message Sent/Received Time as per the user’s time zone. For example User 1 sends a message at 6:30 Indian time, when User 2 would view the message it would show as 2:00 UK time.
Here goes my question, whenever I save the message should I convert it to GMT+00, so all my base times stamps are the same and then later when I display the message, I convert it back to User specific time zone. Would this be complex? Is this the best way of doing this?
I like to get views for both saving and displaying, also when I should do the time conversion from optimization point of view. I would need do deal with any/all timezones.
I am developing this application with PHP and MySQL and I am aware of timezone conversion method come with both PHP and MySQL.
I am just trying to figure out the best way of doing this. Look forward to have all valuable suggestions.
Note : As of now I am not much worried with day/light savings.
Thanks
Ravi
When storing the messages, convert, use and store them in a DST neutral timezone - UTC or GMT, for example.
With them store the original timezone offset and the DST offset - this will help with business logic.
When displaying the message, use this data and convert to the local time.
See this question and answers for best practices regarding working with different time zones.
Here goes my question, whenever I save the message should I convert it to GMT+00, so all my base times stamps are the same and then later when I display the message, I convert it back to User specific time zone. Would this be complex? Is this the best way of doing this?
It is. The only caveat is to allow each user to specify their desired timezone to view times in (either as a preference or from their client system's settings or from user database).
I like to get views for both saving and displaying, also when I should do the time conversion from optimization point of view. I would need do deal with any/all timezones.
The best time to convert from client to GMT is in your "business" logic - basically, whatever logic you have which processes web form data. NOT on the database side.
The best time to convert from GMT to client for viewing is right before/in the presentation layer, e.g. when you're printing your HTML.
The reason is that this way, as little of the code as possible needs to worry about timezones.
NOTE This timezone related logic becomes VERY VERY complicated if/when you need to do any date-specific logic (e.g. aggregate based on date as opposed to merely print timestamp to the user).
When saving data to your database, use something like:
INSERT INTO TableName SET TheDateFile=UTC_TIMESTAMP()
And then, presuming that you allow each user to specify their own timezone, you will need to convert the date in your business logic (as mentioned by DVK)
Something like:
DATE_FORMAT(DATE_ADD(TheDateField, INTERVAL 2 HOUR) // or whatever value
I have not done this myself, but I guess it would be simple enough to store the hour interval as per the users timezone.
In any case if you deal with users which are on different timezones, you must separate the timezone from the date. I heard long time ago that wordpress did it the same way:
First step, determine timezone of the date
Second step, set the timezone of the date to GMT (+0)
Third step, store the timezone and the GMT date in two separate columns.
Anyway, if you need more informations, there's a post here
Related
I ran into trouble while dealing with date and time using php and mysql. I am trying to store local time of user's timezone as a timestamp on mysql db and would like it to convert back to normal date and time at the time of output.
This is the first time I am dealing with date and time.
As I understand: I can't rely on PHP's time() as it returns servers time according to server's timezone and the same case with mysql current_timestamp.
I can use the javascript to get user's local timezone and then can use date_default_timezone_set() for each session.
If I am doing right, now the confusion starts.
As you can understand the users will come from around the globe, so if two users (one from US and another from India) do something at the same time, will it show each others time as identical or it will show some difference? I mean it shouldn't show Indian user that the US user has done something few hours ago as the US user done at same time.
Please let me know if I don't understand these things properly.
What I want to achieve is, the output of the time should show in local time format. Ex: any time should show in IST format for Indian user and other country respectively.
Best way to achieve this is to store date in a database in a standard format (eg. GMT).
After getting user's timezone through javascript, you may convert date to user's timezone & display accordingly.
I'm curious to know if what I'm considering is bad practice, or if since this is a specific and deliberate choice it is actually a decent idea.
I want to store information for dates for events that occur in specific cities. I want to store that data as UTC timestamps.
Wouldn't it be a good idea to simply store the timestamp and the city id/country id (which is associated with a specific timezone), rather than storing the timezone for each event?
I ask because timezones can change, but city IDs would never change in the DB. Once the server is synced with the latest timezone in the (unlikely) event of a timezone change, the event would be independent and unaffected by that change. However, say a timezone changes its boundaries, then events that occurred in that timezone previously could be outside of it.
Does it seem unwise to do this? I'm just wondering, and I've been scouring for best practices but in this case this actually seems like an OK idea. This works particularly because the application design model would never change- events will ALWAYS be associated with a specific city.
The basic flow would be:
Event data with date/location comes into the system in a standard format like ISO-8601 YYYY-MM-DD string.
System converts date to UTC timestamp and stores the date with the event using that timestamp and the city ID for the event.
When a user requests to view that event, the system pulls the timestamp and city information associated with that event, and uses the city's timezone to format the date accordingly on display.
Is this a terrible idea? Is there a benefit to this, and is the concept of storing the TZ Offset the same idea to eliminate this issue?
Scheduling future time is inherently hard, because you don't know what changes are coming in the future. It is a completely different beast than recording past time.
For past time events, all you really need is the local date and time, and the offset from UTC (many platforms call this a "DateTimeOffset").
But for future events, you don't necessarily know what the offset will be. You can guess what it is based upon your current knowledge of the time zone information, but that information is subject to change. In reality, it changes many times per year as governments of the world change their mind about daylight saving time and other situations.
Because you can't determine the offset reliably, you also cannot determine the exact UTC timestamp. So it's important that you hold on to the original local time. If you're going to calculate a UTC timestamp, you should also recalculate that any time you update your time zone data.
I've already written about this multiple times, (here, here and here). I suggest you read those posts.
Now you brought up one point that I hadn't touched on before, otherwise I'd have marked your question as a duplicate. That is - what if the location of the event moves into a new time zone entirely because the time zone boundaries have changed?
I agree with Deceze, that you need to think about how likely this scenario is and how bad a failure would be. In my opinion, it's probably not worth investing a lot of time to. If you have an event scheduled in the future and that location breaks off into a new time zone, you could always go back and edit the event. You need to ask yourself how much detail your app is expected to know about the time zone changes. Most scheduling systems I've worked with don't handle this aspect.
If it is indeed something that you want to handle, then you will need more than just the city. You should store latitude and longitude coordinates for the location. Then you can use one of these methods to resolve the time zone from those coordinates. But also note that you would want to make sure the source of the time zone boundaries was as up to date as possible.
Also note that the IANA Time Zone database that is the original source for the time zone data, does not keep boundary data at all! Most of the boundary data comes from independent sources, such as Eric Muller's shapefiles, which as of today is aligned with the 2013b data of the IANA database (which is at 2013i), so there have been at least 7 updates to the time zone data that either didn't change any boundaries, or the changes were not tracked.
Whichever way you do it, it will fail in different ways depending on what is changing.
If you store timestamps in the according timezone as 2013-12-29 12:34:56 America/New_York, this will fail if, say, the Bronx suddenly starts their own timezone America/New_York_Bronx with a different offset and your event happened to be in the Bronx.
Decide how likely this is and how bad a failure would be.
If you store timestamps in UTC and the timezone in which the event is happening is redefining their offset (e.g. shifting DST dates around, or entirely shifting to a different offset), the event time may differ from the actual wall clock time at that location. If you store 2013-12-29 12:34:56 UTC for an event at 13:34:56 in Berlin, Germany, and Berlin shifts their DST around, 2013-12-29 12:34:56 UTC may now correspond to 14:34:56 Berlin local time, while the event is still actually happening at 13:34 local time.
Decide how likely this is and how bad a failure would be.
If you store the UTC timestamp and link it to a physical location which you then link to a timezone, you can counteract both problems. But for this you'll have to store the precise physical location, not just "New York", otherwise you just have case 1. with one more intermediate step. If you do store the precise physical location and have a precise way to resolve this location to a timezone and you keep your timezone database up to date, you can handle pretty much all change scenarios.
Decide how practical this is and how much this extra precision is worth to you.
When we were migrating our project from UK hosting to US machines, some of the data that was stored as DATETIME was problematic when we had to display data to clients. We had to chage server configuration for time being but it turned keeping dates as strings or date timestamp in db having them dependent from server configuration is not good idea. since then we do use unix timestamps for any dates in the system and we get rid of problem with timezones once for all. Clients decide to use timezone whatever they want to see. It's much easier to calculate time differences, filter data and so on.
The only problem is to make sure entered data into system it's correctly converted to unix timestamp. That means, user who enters the data should have (in your case) event's timezone when date is converted to timezone, otherwise user will need to calculate timezone on his own.
As working on a large application I am trying to make the datetime stamps reconcile with the current user time. so If activity id done at 3:00PM then the every user see it at 3:00PM
So Here is solution steps to the problem. on this and please correct me or lead me to the right direction if I am not on the right direction.
Store all datetime in MySql as UTC time.
Store time zones in a table with the current offset. for example
zone_id zone_name utc-offset
1 Central -6
In my users table I have a field for user_time_zone_id and in that field I will have the value "1" in the user setting so it will say that this user is using the system from "Central" location.
In my php application configuration I set the default time zone to UTC like this
date_default_timezone_set('UTC');
Once I load this application I define the user offset and on each datetime out put I do the calculation of the time. for example date('Y-m-d', strtotime($current_offset.' hour')) where $current_offset = -6 as it is define by the user profile upon the page load.
Here are my questions.
Is my approach to this problem correct?
Is there a better way of doing this?
How to calculate the daylight saving time? Please keep in mind that there are some parts of the country that does not have daylight saving.
I had a similar thing one time, and it ended up being a pain to try to keep track of users timezones and daylight savings, especially when half your clients are in AZ which doesn't have daylight savings. I don't know if this is possible for you, but what I ended up doing was just store everything in UTC and then used JS to convert it to the users local time with the Date object. It was done through an ajax call, but you could also echo a document.write if you needed to.
You shouldn't need to use date_default_timezone_set, use the PHP DateTime class which has native support for timezones. Or, like #romo says, you can do it on the client in JavaScript.
Well I know that this question may be asked many times but certainly I've few doubts In my mind, and by the way don't comment that what I've tried, I've tried many ways but am just asking what's the correct and easier way as there are many posts lingering out here with different suggestions for accomplishing these tasks, so I'll explode() my question into smaller questions...
So can you people just guide me where am going right or wrong as am sure many people are confused when it comes to date/time
1) Why/how to save time as UTC in MySQL using PHP?
Personally for this I post this using php $year/$month/$day and check the date using checkdate() in mysql date field. so is it ok or should I use timestamp and than explode the retrieved string on front end using php?
2) If I run server from India, should I record default time using date_default_timezone_set("Asia/Calcutta"); and than subtract and add time using php function or while posting only I should check users time zone selected from his user accound and accordingly set a condition kinda:
if(timezoneselected == +5.30) {
echo date_default_timezone_set("Asia/Calcutta");
} elseif(timezoneselected == +anytime) {
echo another country timezone
}
3) last question is how websites like gmail facebook etc manages time? I mean if they are saving datetime according to their server than how they show perfect posted time for each user, even gmail, if I send a mail to another user, my sent time and the person living in another country gets email at his printed local time I mean how we can do this, sorry am not able to explain you perfectly say this example,
facebook:
user from India posts, facebook shows posted 8 mins ago, 9mins ago, fine after sometime they show a real date, and that date is perfect according to the time I posted, however if a person from USA updates, say 8 mins ago 9mins ago on his profile but his original posted time is shown correctly to him, and even correctly to me?
sorry for this question but really this will help me understanding this date/time concept and will also be helpful to future users. Thank you!
Bottom line, you should store everything UTC
When you display times for a particular user, use a timezone of their choosing. Store the timezone of the user, like "Asia/Calcutta" and simply convert the time when displaying it using the date_default_timezone_set method.
I will attempt to answer your questions from the comment here.
You store everything UTC always. It is the baseline. When you display the times associated with anything you convert based on the user. If you want to display Posted 8 mins ago then you are taking the delta between the current UTC time and the UTC time associated with a post. If you send a message from user A (in India) to user B (in Los Angeles, USA) then you would store the message time in UTC. If user A is viewing it, the time would be converted to "Asia/Calcutta" and if user B is viewing it, the time would be converted to "America/Los_Angeles". Using UTC will make your life a lot easier. Trust me.
As described in MySQL Server Time Zone Support:
The current session time zone setting affects display and storage of time values that are zone-sensitive. This includes the values displayed by functions such as NOW() or CURTIME(), and values stored in and retrieved from TIMESTAMP columns. Values for TIMESTAMP columns are converted from the current time zone to UTC for storage, and from UTC to the current time zone for retrieval.
Therefore, if you use TIMESTAMP type columns, MySQL will handle timezone conversion for you automatically: just set the appropriate timezone for the session in its time_zone variable.
I have gone through many timezone/PHP posts, and most suggest storing your datetime fields in UTC, then using the application users timezone 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!