I am trying to sync my PHP and MySQL times. Currently the times are different (outputs below):
'SELECT CURRENT_TIMESTAMP' returns '2013-03-16 13:14:28'
'date('Y-m-d g:i:s')' returns '2013-03-16 10:14:28'
I have had success, reading from other users, on changing the MySQL time using SET time_zone='-7:00';. The problem is the time will be changing for different queries based on the user's location and I would rather not change the time_zone for every query.
Should I just set the time_zone once, making it the same time as the server, and then change the time based on the user's timezone in PHP? Or is there a better way to go about this?
Thank you in advance!
Should I just set the time_zone once, making it the same time as the server, and then change the time based on the user's timezone in PHP? Or is there a better way to go about this?
Yes. You also ought not to set timezones via their GMT zone because of daylight savings time. You can write yourself functions to do this conversion by setting date_default_timezone_set('UTC'); and then to your user's timezone.
$time = strtotime('2013-03-16 13:14:28'.' UTC');
echo date('Y-m-d g:i:s',$time); //2013-03-16 9:14:28
Another alternative is to store mysql times in "Unix Time" and then convert only once with PHP.
You definitely want to use a single timezone in your application/database. Only change the timezone of the data (not in the db or your php default tz) if you have to like when displaying to the user - and then only do that right before you about to display it. otherwise, use a single timezone. I prefer GMT
to set the mysql server timezone: in my.conf
have somehthing like this: default-time-zone='GMT'
and then restart mysql
see: http://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html
For php, somewhere at the top of each page you should execute this line:
date_default_timezone_set("GMT");
Related
I am saving a timestamp in my MySQL database with the creation time of a record. When fetching it using CodeIgniter (a PHP framework) it shows in UTC while my timezone is UTC+2. I think that timestamps are stored always in UTC, that's ok, but I don't know how to display it in UTC+2. Same CodeIgniter application in local shows in UTC+2, probably because my computer is in UTC+2 while my server is in UTC.
Is it possible to change a timestamp to another timezone using PHP or a CodeIgniter function, without changing the timezone of either my MySQL server or the web server itself? (I am using a shared hosting, that's why changing the timezone is probably not possible).
Thank you!
You can set the MySQL time zone for your session with something like
SET time_zone = 'Europe/Berlin';
If you give this command immediately after you make your MySql connection each time, you'll always see your TIMESTAMP values rendered in your local time. This uses the so-called zoneinfo database, which is kept current with temporopolitical changes.
The list of zone names is here.
You don't have to change MySQL's global time zone setting to do this.
I am currently studying the best way to handle timezones on my website. People from many different countries will access it simultaneously, and I have to show them time-based information, so I thought:
Store every time on database according to my server (same timezone, defined by PHP)
Then, the user has the option to choose his timezone, and I do the needed conversions by using mysql function DATEADD.
This seems to work fine, but my questions are:
Is this the best way?
Is DATEADD the most efficient function to handle the hour difference?
Thanks.
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.
You are thinking in the right direction.
I would not use the server's timezone. Instead, use Coordinated Universal Time (UTC) time. It is the World Time Standard. This is pretty much the same as Greenwich Mean Time (GMT). Note that UTC does not change with Daylight Savings Time.
TO use in PHP see: http://php.net/manual/en/function.gmdate.php
From here, you can either add hours via: http://www.php.net/manual/en/datetime.add.php
Or set the timezone based on the users preference: http://www.php.net/manual/en/datetime.settimezone.php
The one you use is based on how you get the user's timezone. If you ask them for it (most accurate) you can set the timezone in PHP with the user selecting from a combo box. If you get it from the header with JavaScript using getTimezoneOffset(); then it is best to add hours based on the timezone offset.
I personally set all the times in my DB according to the GMT +0.00 timezone. So I use UTC_TIMESTAMP() (or UTC_DATE(),UTC_TIME() - whichever applies) when I want to add the current time, for example. This is server independent so I'm confident that even if I change my server I will not need to worry about this issue in the future.
Then the options are, if your visitors have a chance to pick their own timezones, you can use the DATE_ADD() and DATE_SUB() functions to format the result before providing results.
Otherwise if you have the chance (this is my favorite solution) you can use Javascript to format that date/time, which you can make it handle easily by something like
function getLocalDate(dt) {
var d = new Date(0);
d.setUTCSeconds(dt);
return d.toLocaleDateString();
// or in some format that you choose
}
which gets the date echoed by PHP using strtotime($row['some_date']);.
SOmewhat related to Doing calculations in MySQL vs PHP
Right now, our database assumes that the system time is in UTC and uses that to calculate NOW(). PHP explicitly sets the timezone as UTC (so its impervious to server time zone shifts).
An accidental shift of timezones on the server messed this relationship up at the database level and i'm now trying to figure out the ideal congiguration:
configure Mysql to be in UTC, but also from the perspective that:
our application may be on someone else's server where they might have a different TZ (so i cant set the timezone at the mysql/server level). How do i configure it at the specific database level?
You should check out UTC_TIMESTAMP(); this ensures that a timestamp field is always UTC in the database. Have your PHP script do the offset from the users browser information. This can also be done using DATE_ADD/DATE_SUB or better CONVERT_TZ().
Have PHP set it before you store it in the database. Have it set to GMT and then calculate when displaying based on the users timezone as needed.
My server is in Dallas. I'm in New York City.. and both PHP and MySQL have configuration variables for setting the timezone.
How do I get them all to work together? What dates should I store in MySQL? How do I get PHP to handle changing the date based on the user's preference?
Bear in mind: I don't think I'm ever having PHP explicitly set the date, it's always using "NOW()" in queries.. however I foresee the need to do this. How would this be done?
I'm hoping SO's experience can help me out here.
Use Unix Time everywhere. It's using UTC so it's the same for every timezone. Methods for dates usually convert to it and back from it using timezone information they have, so you would have yourself a correct time.
Alternatively you could use Unix Time only to transfer time from one computer to another (like from DB to your server running PHP, or to JavaScript client). There's functions to convert to it and from it in every language. For MySQL it is:
UNIX_TIMESTAMP(date)
FROM_UNIXTIME(unix_timestamp)
That way you could have your time properly formatted on the DB and in logs but still have correct local time everywhere.
I prefer using dates and times in the native form with respect to the environment, that is, Unix timestamps in PHP and DATE/TIME/DATETIME/TIMESTAMP fields in MySQL. I translate both values into another using FROM_UNIXTIME() and UNIX_TIMESTAMP(). I prefer this instead of Unix timestamps, because native dates/times are much easier to read.
Record your dates in GMT (zero offset) and then calculate the offset based on the local timezone (EST is +6, for example, so you'd add 6 hours to the GMT).
Check the Date docs for the date_default_timezone_set() function.
Just remember, when writing to the database, you'll have to change time zones, store the date, then change back. Likewise, when you're retrieving the date, don't forget to add the timezone offset.
The mysql-server stores dates in a timezone independent format (UTC).
But before it stores the date it will be converted using its timezone.
U can change the mysql timezone per connection *1:
mysql_query('SET time_zone = "'.$timezone.'"');
You can also change the timezone per script.
date_default_timezone_set($timezone);
If you set them to the same timezone "2009-01-10 13:30:00" will mean the same thing to both mysql and php.
But keep in mind that the 2 servers have different internal clock values, so if you want to generate timestamps based on current time. Do that in mysql OR php.
*1)
MySQL timezone support may require additional configuration. check the manual
For those of us who use standard shared hosting packages, such as GoDaddy or Network Solutions, how do you handle datetime conversions when your hosting server (PHP) and MySQL server are in different time zones?
Also, does anybody have some best practice advice for determining what time zone a visitor to your site is in and manipulating a datetime variable appropriately?
As of PHP 5.1.0 you can use date_default_timezone_set() function to set the default timezone used by all date/time functions in a script.
For MySql (quoted from MySQL Server Time Zone Support page)
Before MySQL 4.1.3, the server operates only in the system time zone set at startup. Beginning with MySQL 4.1.3, the server maintains several time zone settings, some of which can be modified at runtime.
Of interest to you is per-connection setting of the time zones, which you would use at the beginning of your scripts
SET timezone = 'Europe/London';
As for detecting the client timezone setting, you could use a bit of JavaScript to get and save that information to a cookie, and use it on subsequent page reads, to calculate the proper timezone.
//Returns the offset (time difference) between Greenwich Mean Time (GMT)
//and local time of Date object, in minutes.
var offset = new Date().getTimezoneOffset();
document.cookie = 'timezoneOffset=' + escape(offset);
Or you could offer users the chioce to set their time zones themselves.
Store everything as UTC. You can do conversions at the client level, or on the server side using client settings.
php - date
mysql - utc-timestamp
RE the answer from Željko Živković, timezone descriptors like 'Europe/London' only work if the mySQL admin has added the timezone tables to the system, and keeps them updated.
Otherwise you are limited to numeric offsets like '-4:00'. Fortunately the php date('P') format provides it (as of 5.1.3)
So in say an app config file you might have
define('TZ', 'US/Pacific');
....
if (defined('TZ') && function_exists('date_default_timezone_set')) {
date_default_timezone_set(TZ);
$mdb2->exec("SET SESSION time_zone = " . $mdb2->quote(date('P')));
}
This means PHP and mySQL will agree on what timezone offset to use.
Always use TIMESTAMP for storing time values. The column is actually stored as UNIX_TIME (epoch) but implicitly converted from current time_zone offset when written, and back when read.
If you want to display times for users in other time zones, then instead of a global define(), set their given timezone in the above. TIMESTAMP values will be automatically converted by mySQL by the time your app sees the result set (which sometimes can be a problem, if you need to actually know the original timezone of the event too then it needs to be in another column)
and as far as, "why not just store all times as int's", that does lose you the ability to compare and validate dates, and means you always have to convert to date representation at the app level (and is hard on the eyes when you are looking at the data directly - quick, what happened at 1254369600?)
I save all my dates as a bigint due to having had issues with the dateTime type before. I save the result of the time() PHP function into it, now they count as being in the same timezone :)
In php set timezone by in the php.ini file:
ini_set("date.timezone", "America/Los_Angeles");
or in particular page you can do like:
date_default_timezone_set("America/Los_Angeles");
In mysql you can do like:
SET GLOBAL time_zone = 'America/Los_Angeles';