MySQL: using timestamp, how to convert to my user's timezone? - php

In my LAMP application, I'm storing certain date/time stamps using the timestamp data type in MySQL. From my understanding, this will automatically convert to UTC when saving and converted back from UTC when retrieving. The conversion back from UTC depends on the time zone settings of the server where MySQL is installed, right?
What if I want the timestamp converted into whatever time zone my user is in? How do I query SQL to return those timestamps into a specified time zone? My server's time zone is useless to my users, unless they so happen to be in the same timezone I guess.

Similar to this question ( Detect user timezone and display UTC time with that timezone ) , you can do it as follow :
Detect user timezone offset
Calculate the difference between MySQL / Web Server's timezone
Apply your logic
UPDATE: another related question here : Determine a User's Timezone

I think you want the CONVERT_TZ function .

Related

Setting UTC as time zone in PHP and MySQL

I'm working on an application and I ran into a little problem...
How do I work with time zones and will there be conflicts between PHP and MySQL? What I was thinking of doing is setting the time zone to UTC in PHP like this date_default_timezone_set('UTC'); and storing it in MySQL using DATETIME.
Will MySQL change the time I provide via PHP to whatever time zone it has set or will it just store the value provided? If it will change it, how can I set the time zone in MySQL to UTC as well.
I would like to set the time zone to UTC so if I ever do need to worry about changing time for different time zones, I can just add/subtract whatever the offset is.
P.S. I'm new to web development.
Use below code to extract TimeZone Offset value. Then add it to your actual date time value. It will convert your Date Time value to UTC time.
set #TimeZoneOffSet := TIMEDIFF(NOW(),UTC_TIMESTAMP);
select ADDTIME(date_time_column,#TimeZoneOffSet) from table_name;;

What's sufficient for storing timezones?

I need to store client timezones and am wondering if I need to take DST into consideration. All I care about is displaying the user's local timezone and if DST is in effect, then the system should reflect it.
Is it enough to set the user's timezone using date_default_timezone_set and assume that DST will be automatically calculated if there is one for that area?
Is there anything else that I need to do to safeguard that the user be shown the correct time?
EDIT:
Some great answers here, thanks.
If I store the users timestamps in UTC, regardless of their actual timezone and I use date_default_timezone_set to convert the UNIX timestamp, will the correct time be displayed if there is a DST present?
It is probably best to store dates and times as the UTC+0. When you print out dates to the user in PHP, functions like date() accept a timestamp argument. These functions also automatically converts the timestamp to the current timezone. Timestamps are always UTC+0.
In a PHP script, you can change the default timezone like this:
date_default_timezone_set("Europe/Oslo");
After that, I get this result while running date("r"):
Sun, 27 Oct 2013 11:22:52 +0100
When you use geographic timezone names, times will be converted to the correct timezone depending on which time of year it is. In my example, "CET(GMT+1)" is chosen now, but yesterday it would have given me the daylight savings timezone "CEST(GMT+2)".
To store the current time in for instance a database, you can usually just store timestamps as integers (INT(11)). The current UTC+0 timestamp is in PHP retrieved with time().

Timezone offset issue

Working on a mod where a user inputs a datetime in this format "11/28/2012 11:34 am".
I am then using strtotime to convert it to a timestamp and saving it to my database.
I am then displaying it to the user in my template using the following date(DateTime, 'D M jS g:i A').
The problem is users who are not in the same timezone as the user who created the event do not get the correct time updated to reflect their timezone.
I have access to both timezone offset's of the user posting and the user viewing.
MY question is how should I compensate for timezone differences?
When converting the string to the real timezone use this to override server time zone with time zone of the user submitting the value: http://us3.php.net/manual/en/function.date-default-timezone-set.php
When retrieving it later, use the same function to override server time zone to current user's one (the one that is appropriate for the user displaying datetime at the moment).
Also make sure you store it properly in the database: preferably using Unix timestamps within PHP, TIMESTAMP columns within database, FROM_UNIXTIME() database function when saving to the database and UNIX_TIMESTAMP() when retrieving from database (all are valid for MySql RDBMS, check your own DBMS if it is different).

Handle time from different timezone and store into mysql

I making a website with facebook,
the bad thing is.. there is too many timezone and hard to convert into UTC.
my server is using UTC as default setting,
may i know how could i manage it in more generic way, to convert difference time zone into UTC time, and display it into preset timezone setting ?
additionally, may i know how could i store this into mysql database with php ?
2011-04-10T08:13:30+0000
Use gmdate() function, it formats the time in UTC.

PHP, Codeigniter: How to Set Date/Time based on users timezone/location globally in a web app?

I have just realised if I add a particular record to my MySQL database - it will have a date/time of the server and not the particular user and where they are located which means my search function by date is useless! As they will not be able to search by when they have added it in their timezone rather when it was added in the servers timezone.
Is there a way in Codeigniter to globally set time and date specific to a users location (maybe using their IP) and every time I call date() or time() that users timezone is used.
What I am actually asking for is
probably how to make my application
dependent on each users timezone?
Maybe its better to store each users timezone in their profile and have a standard time (servers time) and then convert the time to for each user?
Thanks all
It sounds like what you need to do is store all of the date and times in your system as UTC time (used to be called GMT). This is the base time that everything in the world is calculated off of with adjustments. (eg: Central Time is -6 hours off of UTC)
In MySQL you can use UTC_TIMESTAMP() to get the current UTC time as long as your server and DB are configured with the correct times and timezone settings.
In PHP run this to set the timestamp of PHP to UTC (you will run this in your code so put it on every page or in a centralized index file):
date_default_timezone_set('UTC');
Or you can go directly into PHP.INI and tell it to use UTC time globally. (this may not work if you have multiple websites on a single installation of PHP.
And then anywhere in the system you need to get the current UTC time you can just call:
time();
Then for each user in the system you will need to ask them what timezone they live in and then when you display times make the adjustment for that user. So if it is 5:00PM UTC and I live in Easter US (-5) the time would be 5:00 - 5 hours = 12:00PM.
This can be a long process to get right but once you do your users will find it very useful especially internationally.
I think the easiest way is define a timezone for internal data storage (your server's time zone or UTC) and convert the time according to the user's time zone when outputting it.
I don't know CodeIgniter so I can't point you to the right functions. One prominent library that is timezone aware is Zend_Date: Working with Timezones I have not worked with these functions yet but they look promising.
However, once you know the user's time zone, it's not difficult to put together an own function that adds/substracts the offset when outputting dates and/or times.
Possibly related question:
MySQL: keep server timezone or user timezone?
Take an example of an existing web application such as WordPress and phpBB. Each user have their own timezone setting.
When receiving a content from the user, use local_to_gmt() function in the Date Helper then save the content into database using the gmt date. When fetching the data you will get the time in gmt. Get the user's timezone setting, then display the data in that timezone.
This way, you can save yourself from calculating between two timezone. Just make sure that your server's time is in correct setting, so all your data is in the correct gmt time.
UPDATE:
Recently I review the last project I worked on that have timezone issue. After thinking various scenario, here is the solution for the timezone issue:
All data stored right now already
using server's time. Changing this
will takes times and prone to error,
so I leave it like that.
For the new data from user that set the content date to a certain
date and time, I stored it into 2
column. First column is to store the
data as is, and used to displaying
it as is. Second column will be a
recalculation of the date based on
the user's timezone into server's
timezone. This column is used in the
WHERE statement (filter based on
server date) and for the ORDER
(because this column's value all in
same timezone, which is the server's
timezone).
This way, I only do 1 timezone calculation, which is to convert user date into server date. For displaying , I display the date according to server's datetime. Since all data stored in the same timezone, data can be ordered by the column that hold the server date value.
For the user that have set their timezone, the date from database can be easily recalculated to get the datetime in the user's timezone. Btw, in my application, I display the date using timeago jquery plugins. This plugins need time in the ISO8601 format (UTC time). local_to_gmt() function in CodeIgniter can be used to do this.
Obviously the leap to British Summer Time (Daylight Savings Time) is a big confusion in the world of programming, and I am indeed caught up in that confusion.
The best possible solution I can find (which I will try to coherently explain) when using a timezone sensitive system is this:
The Web Server and Database should both be running off the same machine timezone. I suggest UTC as it is the building blocks of timezone conversions. This will ensure that all of the dates stored in your database are constant, and don't skip any times such as the 1hour jump between Daylight Savings.
At the top of all of your PHP scripts use date_default_timezone_set('Europe/London'); with the specific timezone of the user.
When producing dates from user submitted forms, use gmmktime(); to ensure that the timestamp created is UTC and not altered by the timezone that you have set.
date(); can be used when displaying dates, as this will convert the timestamp to the correct time taking into account the timezone that you have set.
If you do need to show a date in the UTC format then use gmdate(); with the $gm_timestamp that you have taken from the database or created with gmmktime();.
I have written this bit of PHP to help understand the situation.
date_default_timezone_set('UTC');
$gmtime = gmmktime(2,0,0,03,29,2009);
$time = mktime(2,0,0,03,29,2009);
echo $gmtime.'<br />'.date('r',$gmtime).'<br />'.gmdate('r',$gmtime).'<br />';
echo $time.'<br />'.date('r',$time).'<br />'.gmdate('r',$time).'<br />';
date_default_timezone_set('Europe/London');
$gmtime = gmmktime(2,0,0,03,29,2009);
$time = mktime(2,0,0,03,29,2009);
echo $gmtime.'<br />'.date('r',$gmtime).'<br />'.gmdate('r',$gmtime).'<br />';
echo $time.'<br />'.date('r',$time).'<br />'.gmdate('r',$time).'<br />';
Hopefully I've done a good job, but I doubt it because I'm still trying to battle the problem in my head.
UPDATE:
Glad I did this, because I am now having doubts about the user inputted dates.
To get the User inputted date (taking into account their timezone) to match up with the UTC corresponding date in the database, you should put it through mktime(). And then use gmdate('U', $timestamp); to get the true UTC timestamp. (I think)
Example
Looking at it from a reporting side, the user is using the 'Europe/London' timezone. At the start of our PHP script we call date_default_timezone_set('Europe/London');, whilst the Database (and all the records within) is still in UTC.
The user then sends through that they want to select a list of books added to the database between 25/03/2010 10:00 to 30/03/2010 14:00. The PHP script then runs the date variables through mktime($hour, $minute, $second, $month, $day, $year) to generate a correct UTC timestamp. The start date will not change, but PHP knows that the end date is within the BST timezone, so changes the timestamp to UTC accordingly.
When the results are returned back to the user, date('r', $date_added) can be used to show the user the date the book was added to the database according to their set timezone.
This link may help with understanding when it changes. http://www.daylightsavingtime.co.uk/
I think recalculating to user's time is better option, since it gives you normalized time on server, i.e. if you'll need to look up something, that happened (from your point of view) hour ago, you won't have a mess with american, asian and e.g. australian time.
Just ask them for their timezone (usually select with major cities in that timezone) and then recalculate :)
Or, alternatively, you can store two timedates - one for your comparison and one to show, so you won't have so much calculations on serverside.
Also, if recalculating, you can use date helper:
http://ellislab.com/codeigniter/user-guide/helpers/date_helper.html
I've used the MySQL built-in timezone conversion. In the database, all datetimes are stored as UTC. In the select query, I used CONVERT_TZ to convert to the user's timezone. You can specify timezone codes or hour invervals like:
SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
But, the problem is this does not accommodate for daylight savings times. This is particularly frustrating since many parts of the world either don't honor daylight savings or honor it on different dates. So, if you install the timezone description tables, you can use descriptive names that will account for daylight savings automatically like:
SELECT CONVERT_TZ('2004-01-01 12:00:00', 'UTC', 'US/Eastern');
Codeigniter contains a helper which deals with all manner of date functions.
Codeigniter Date helper
the command gmt_to_local() should help you... the third parameter is for 'daylight_saving'.
Takes a Unix timestamp (referenced to GMT) as input, and converts it to a localized timestamp based on the timezone and Daylight Saving time submitted. Example:
$timestamp = '1140153693';
$timezone = 'UM8';
$daylight_saving = TRUE;
echo gmt_to_local($timestamp, $timezone, $daylight_saving);
Add this line to autoload.php in the application folder/config folder:
$autoload['time_zone'] = date_default_timezone_set('Asia/Kolkata');

Categories