PHP - How to cater for timezone - php

I have setup a web app for a client. The server is in US I believe. The client himself is in Sydney.
He says he added a record to a table with a timestamp field and it shows the timestamp as 2010-11-19 07:12:00 but the actual local time has been 2010-11-20 13:12:00.
So he is 30 hours ahead of the time recorded. This doesn't look right, how could the offset be greater than 24 hours? And what should I change/use so he sees correct date/time?
Edit:
Would it be correct approach to add 30 hours to current time before inserting the record?

First thing is to check the time on the server. Make sure that is correct.
To fix the issue, you have to know the offset for the user, so this will either need to be a recorded in a user profile, or if it is stationary for the whole application, you can set the server's time to correspond with his timezone.
Another option is using PHP's DateTime Class.
Another option would be to use certain Timezone Setting functions PHP offers.
A final option would be to set the timezone setting for MySQL this requires you to add items to the startup options, so you will need to edit the startup script for MySQL.

If the offset is 30 hours, then the culprit can't possibly be the time zone. Or at least, it can't be the only culprit. Without more details, that's the best I can do.

Sydney, Australia is GMT+10. The east coast of the US is GMT-5. That's a 15 hour difference.
Could be a coding error, where the timezone is getting corrected twice.

Related

How to get around your host having the mySQL database on a strange timezone

I'm struggling with an inept hosting company who have taken over my previous hosting company. Apart from everything else they broke in the migration, the mySQL database is set to Australian time (unsure which city). I can set the PHP environment timezone by adding a php.ini file, but that still leaves the database in an odd state.
I think logically a host's database should be on UTC, and they should install the mysql timezone tables (but alas no, this will take weeks of badgering their "help"desk to get anywhere). I do not have permission to set any of the SQL variables of course (and without the timezone tables it will all be for nothing).
Now, I could get around this with an offset - I know the host is on +10hours, I need +12 hours, BUT this will all go wrong with daylight savings time (the australian one and my local one will not change at the same time).
And I run a booking system, so letting users book things 1 hour in the past will not go well...
So - as I have the PHP environment working, my solution is to get the offset from the PHP environment
$d = new DateTime();
echo $d->format('Z');
This gives me the offset in seconds -- divide this by 60*60 and we get the current current offset for my timezone. I believe this will change with daylight savings.
so I get an offset of +12 hours
Now I can apply this in the SQL, as the UTC_timestamp() function works, I can do
select CONVERT_TZ (UTC_TIMESTAMP, '+0:00', '+12:00');
to get the current date and time.
Should it be this hard to work around inept hosting companies? Is there an easier way??

Day light saving time and repeating events. What should I store?

We have the same system as Google Calendar Events now you can create an event and it will notify you at that time.
PHP cron job will run every 15 minutes, now the settings can be set to send mails every day or weekday or weekend, or every 2nd day of month or weekend. And it can be repeated for few occurrences or forever so we can not store UTC value in the table.I know I can store the UTC for next event and update that column for next event. But I think, there should be a better way to do this then changing UTC on each occurance.
we have a field which was storing offset time "-04:00" or "-05:00" on the basis of timezone you choose.
We had EST, EDT, CST, CDT, PST, PDT, MST, MDT in our drop-down earlier. on the basis of chosen value, we have saved offset in DB which is an incorrect way.
Now when DAYLIGHT SAVING time changes user has to move from EST to EDT or vice versa. Now we want to solve this problem that user does not have to change there settings.
Want to have a drop-down which has "Eastern, Central, Mountain, Pacific" and want to store the value in DB.
What value should be stored ? as we do not want to store offset as it will change with DST and it will be an incorrect way.
Another thing how it works. Our servers are in UTC. we have a custom function in MySQL named "isItCorrectTimeToDoThis" which checks that is there any events are present at this time in UTC in time zones. in this function, we are using the CONVERT_TZ function. We have cron job which runs every 15 minutes but a query to get events is in MySql. I hope you guys have understood this part.
We have Timezone tables installed in our server.
WHat should be stored in db table field timezone "EST", "EDT" or "US/Eastern".
1> I am not able to find what will be the output of CONVERT_TZ(now(),'UTC','EST'); when DST is on.
OR
2> I am not able to find what will be the output of CONVERT_TZ(now(),'UTC','EDT'); when DST is off.
Or
3> CONVERT_TZ(now(),'UTC','US/Eastern')
Which one will handle Daylight savings accurately? That user does not have to change their settings again and again.
Just store the time in UTC and just render the time for the local timezone of the user. This is the best option. The only conversion will be in the UI and that is the only place where you should care for time zones.

WordPress - How do I set error log timestamp timezone to local?

WordPress uses UTC / GMT for all its timestamps in the PHP error log. I would like to have the timestamps in the local server timezone. Changing the timezone in WP settings does not help; this affects time displays but not timestamps in the error log.
(I know there is a line in the wp_settings.php file which sets this, and I am given to understand changing that setting messes up parts of the WP code hardcoded to use UTC.)
I have looked at overriding the PHP error_log function to parse the time and replace it, but the two methods I found required having something extra installed (APD or Runkit). As I understand it, these are for DEV environments only, so I don't want to mess with them.
Any suggestion on how to get WP to write local timezone stamps to the error log?
There's a reason for logging time in UTC. Many time zones use daylight saving time. For those zones, there's an hour in the spring that is skipped, and an hour in the fall that is duplicated. If you were to log using the local time, there would not be an easy way to disambiguate between the duplicated values.
For example, if you are in the US Eastern time zone ("America/New_York") and you logged using local time, a value like 2014-11-02 01:30:00 could mean either 1:30 in Eastern Daylight Time, or 1:30 in Eastern Standard Time - an hour later.
If you log frequently enough, you might be able to detect this by comparing the timestamps of other items in nearby log entries. But in general, that's not a great solution because you might only log occasionally, or you might not want the overhead of analyzing more than one log entry at a time.
Besides daylight saving time - there's also the issue that if you take log files from multiple servers, they should be able to be compared uniformly. Perhaps I have web servers on the US East coast and West coast, one in Europe, and one in Japan. If there's a spike in my global traffic - I shouldn't have to do time zone conversions to line things up.
If you really must log in local time - then consider including the offset from UTC along with the timestamp. This is known as a "DateTimeOffset" in some languages, and is also part of the ISO-8601 standard. For example, "2014-06-20T01:23:45-07:00". By doing this, you at least allow for conversion back to UTC and remove any ambiguity caused by daylight saving time.
I don't know if there's a specific way to have WordPress or PHP log in this manner, but perhaps someone else can offer that as a separate answer.
Just set the preferred timezone in functions.php
date_default_timezone_set('Asia/Kolkata');
Change 'Asia/Kolkata' with your preferred timezones. PHP Official timezone
Better to use child-theme to preserve changes made in functions.php even after the theme gets updated.

How to calculate time zone offset for a large application?

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.

Managing timezones

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!

Categories