300

Does anyone know if there is a function to obtain the server's time zone setting in MySQL?

UPDATE

This doesn't output any valid info:

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+

If MySQL can't know the exact time_zone being used, that's fine - we can also involve PHP as long as I can get valid info (not like SYSTEM)

3pitt
  • 899
  • 13
  • 21
user198729
  • 61,774
  • 108
  • 250
  • 348
  • 4
    "we can involve PHP here" - and would that instance of php always be on the same machine as the MySQL server? – VolkerK May 29 '10 at 08:55
  • Yes,they'll be on the same machine. – user198729 May 29 '10 at 09:02
  • 18
    Try `@@system_time_zone` as stated in my answer below. – Andrew Nov 24 '11 at 20:29
  • Since the question was asked more answers were added, maybe reconsider the accepted answer? – Timo Huovinen Apr 03 '14 at 09:11
  • 2
    Even though the MySQL server and PHP are on same server, they may pickup different timezones based on their settings. And these times can differ from what your OS shows, and PHP/MySQL show. – Bimal Poudel Jul 30 '14 at 13:40
  • It does output valid info, it tells you that mysql timezone is the same as your system's timezone – Rombus Sep 05 '17 at 13:54
  • Over at https://stackoverflow.com/questions/930900 is explained how to override SYSTEM in the config file `my.cnf`. Under section `[mysqld]` add `default-time-zone='Pacific/Chatham'`. – cachius Dec 11 '20 at 16:46
  • `select timediff(current_time(),utc_time()) as td, @@system_time_zone as tz;` – Eric Jul 19 '23 at 12:32

19 Answers19

300

From the manual (section 9.6):

The current values of the global and client-specific time zones can be retrieved like this:
mysql> SELECT @@global.time_zone, @@session.time_zone;

Edit The above returns SYSTEM if MySQL is set to use the system's timezone, which is less than helpful. Since you're using PHP, if the answer from MySQL is SYSTEM, you can then ask the system what timezone it's using via date_default_timezone_get. (Of course, as VolkerK pointed out, PHP may be running on a different server, but as assumptions go, assuming the web server and the DB server it's talking to are set to [if not actually in] the same timezone isn't a huge leap.) But beware that (as with MySQL), you can set the timezone that PHP uses (date_default_timezone_set), which means it may report a different value than the OS is using. If you're in control of the PHP code, you should know whether you're doing that and be okay.

But the whole question of what timezone the MySQL server is using may be a tangent, because asking the server what timezone it's in tells you absolutely nothing about the data in the database. Read on for details:

Further discussion:

If you're in control of the server, of course you can ensure that the timezone is a known quantity. If you're not in control of the server, you can set the timezone used by your connection like this:

set time_zone = '+00:00';

That sets the timezone to GMT, so that any further operations (like now()) will use GMT.

Note, though, that time and date values are not stored with timezone information in MySQL:

mysql> create table foo (tstamp datetime) Engine=MyISAM;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into foo (tstamp) values (now());
Query OK, 1 row affected (0.00 sec)

mysql> set time_zone = '+01:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |      <== Note, no change!
+---------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 10:32:32 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 08:32:38 |      <== Note, it changed!
+---------------------+
1 row in set (0.00 sec)

So knowing the timezone of the server is only important in terms of functions that get the time right now, such as now(), unix_timestamp(), etc.; it doesn't tell you anything about what timezone the dates in the database data are using. You might choose to assume they were written using the server's timezone, but that assumption may well be flawed. To know the timezone of any dates or times stored in the data, you have to ensure that they're stored with timezone information or (as I do) ensure they're always in GMT.

Why is assuming the data was written using the server's timezone flawed? Well, for one thing, the data may have been written using a connection that set a different timezone. The database may have been moved from one server to another, where the servers were in different timezones (I ran into that when I inherited a database that had moved from Texas to California). But even if the data is written on the server, with its current time zone, it's still ambiguous. Last year, in the United States, Daylight Savings Time was turned off at 2:00 a.m. on November 1st. Suppose my server is in California using the Pacific timezone and I have the value 2009-11-01 01:30:00 in the database. When was it? Was that 1:30 a.m. November 1st PDT, or 1:30 a.m. November 1st PST (an hour later)? You have absolutely no way of knowing. Moral: Always store dates/times in GMT (which doesn't do DST) and convert to the desired timezone as/when necessary.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Just curious, why do we have to set the time zone ourselves and then retrieve it? That kind of defeats the purpose doesn't it? I mean, I'd like to ask MySQL for the timezone because I don't know the answer. Maybe I am confused and got things wrong. Can someone explain? – Senthil May 29 '10 at 08:43
  • 1
    @Senthil The mySQL `DATETIME` type does not contain timezone info. Therefore, I think the intended underlying philosophy here is for mySQL to be as timezone blind as possible - which means for the user to stick with one time zone, either UTC or the time zone the server is in, store everything in that zone, and do any conversions on application level or using `CONVERT_TZ()` (http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_convert-tz) At least, that's how I always understood how it's supposed to work, looking at the sparse options mySQL provides in this field. – Pekka May 29 '10 at 08:47
  • Thanks but this still isn't solved yet,how do I get the tz info by the result of `now()` in PHP? – user198729 May 29 '10 at 08:49
  • I totally agree with the "stick to one timezone when saving timestamp" part.. But this-> "..or the timezone the server is in.." how do you find that out? Let's say you saved all the timestamp values as UTC. But your server is in someother timezone and you want to show the timestamp values according to **that** timezone. So how will you know which timezone your server is in? Only then you can pass on some value to CONVERT_TZ() to convert it right? – Senthil May 29 '10 at 08:53
  • @user198729: I've just updated the answer, but again, the best way frankly is to set the timezone yourself on your connection (as the answer already said), since all that's affected is the functions you'll be calling, *not* data stored in the server. – T.J. Crowder May 29 '10 at 08:54
  • I hope the answer to my question is not - **don't you know which timezone your server is in? ask your hosting provider!**.. – Senthil May 29 '10 at 08:56
  • @Senthil: You should *never* store datetime values in the database in anything other than GMT, unless you *also* store the timezone it's using alongside the value. So by and large, you don't care what timezone the server is using. About why you can't query it, I'll *speculate*: `SYSTEM` basically means that MySQL asks the OS for the current local time; it probably doesn't actually know what timezone the OS is using. Although it would be possible for the MySQL developers to query the TZ of the OS and report that, it looks like they just didn't think it was important enough to bother. – T.J. Crowder May 29 '10 at 08:56
  • @T.J. Crowder , I can't assume the `SYSTEM`,that's like hardcode. I'd like to see how to get tz from the `now()` in PHP,but don't know if there is such a function. – user198729 May 29 '10 at 08:57
  • @user198729: I never said anything about assuming things (which, agreed, is a very bad idea). I think if you go back and re-read my answer thoroughly, you'll see how to get that information (to the extent you can) and why you probably don't want to (because it tells you nothing about the dates stored in the DB). – T.J. Crowder May 29 '10 at 09:00
  • Hmmm... your speculation came close to my expected answer in terms of silliness... "just didn't think it was important enough to bother" :D – Senthil May 29 '10 at 09:00
  • Not exactly,I think the possible solution is to compare `now()` in MySQL and `time()` in PHP,right? – user198729 May 29 '10 at 09:04
  • @Senthil: (Re silliness) Yeah. :-) – T.J. Crowder May 29 '10 at 09:09
  • @user198729: I've just added further discussion to the end of the answer, I'm off, good luck with it. – T.J. Crowder May 29 '10 at 09:10
  • I decide to accept this answer,though it's not a general solution that can handle all cases,but it DOES solve my specific case:) – user198729 May 29 '10 at 09:19
  • -1 for a couple of reasons. Most importantly, the claim that *knowing the timezone of the server is only important in terms of functions that get the time right now* is not entirely true; as [the manual](http://dev.mysql.com/doc/refman/5.7/en/datetime.html) notes, the `timestamp` type, unlike the `datetime` type, converts times from the server's timezone to UTC upon storage and back again upon retrieval - hence your experiment at the MySQL shell *would* show a change using the `timestamp` type. – Mark Amery Oct 05 '14 at 18:41
  • If you have no objection, and if I find the time, I might try to tidy this up at some point to scrap the PHP-based solution, replace it with [Unix-specific](http://superuser.com/questions/309034/) and [Windows-specific](http://www.windows-commandline.com/find-time-zone-command-line/) instructions on how to check the system timezone, correct the passage about the role that the server timezone plays to expand upon the `timestamp` vs `datetime` behaviour difference, and note that [ways of getting the current timezone offset with pure MySQL](http://stackoverflow.com/a/3984412/1709587) exist. – Mark Amery Oct 05 '14 at 18:47
  • @MarkAmery: Posting it as a separate answer would be the most appropriate thing. – T.J. Crowder Oct 05 '14 at 21:22
272

The query below returns the timezone of the current session.

select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));
James McMahon
  • 48,506
  • 64
  • 207
  • 283
JohnZ
  • 2,721
  • 1
  • 14
  • 2
  • 8
    This is really the right answer, because it demonstrates that 'SYSTEM' is recognized as a timezone in conversion, making it fully sufficient to convert e.g. NOW() into any timezone. – nilskp Oct 03 '11 at 19:02
  • 5
    Thanks, using this I was able to get the format I wanted: `select time_format(timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')),'%H%i');` – jordanbtucker Aug 08 '12 at 20:04
  • 132
    `SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)` is simpler. – Jakub Vrána Apr 11 '13 at 17:04
  • 3
    Or `SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);` to get the difference in seconds. – philfreo Sep 14 '15 at 01:00
142

Simply SELECT @@system_time_zone;

Returns PST (or whatever is relevant to your system).

If you're trying to determine the session timezone you can use this query:
SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone);

Which will return the session timezone if it differs from the system timezone.

Andrew
  • 8,363
  • 8
  • 43
  • 71
  • 8
    The only downside is that if the timezone changes due to Daylight saving time changes it will still report the one which was "remembered" at the time of starting the server, see [mysql bug 9518](http://bugs.mysql.com/bug.php?id=9518) – Mark May 27 '13 at 11:54
  • There is also another downside - looks like it returns something in system locale, so it can display something like �������� ���� (����) – Timofeus Aug 03 '21 at 05:35
91

As Jakub Vrána (The creator or Adminer and NotORM) mentions in the comments, to select the current timezone offset in TIME use:

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

It will return: 02:00:00 if your timezone is +2:00 for that date

I made a cheatsheet here: Should MySQL have its timezone set to UTC?

Community
  • 1
  • 1
Timo Huovinen
  • 53,325
  • 33
  • 152
  • 143
  • Or `SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);` to get the difference in seconds. – philfreo Sep 14 '15 at 01:00
  • add-on to @philfreo - note that the parameters should be reversed in TIMESTAMPDIFF compared to TIMEDIFF. To take the example given in this answer, if TIMEDIFF returns `02:00:00`, the corresponding TIMESTAMPDIFF would return `-2` if unit is HOUR, `-120` if unit is MINUTE, etc. To get the sign to correspond to the timezone, swap the parameters: `SELECT TIMESTAMPDIFF(MINUTE, UTC_TIMESTAMP, NOW())` will return the expected `120` for timezone +2:00. The reason to specify minutes, is there are a few timezones that are 30 or 45 minutes offset, see https://en.wikipedia.org/wiki/Time_zone – ToolmakerSteve Aug 03 '16 at 04:22
  • 1
    this is a much better answer than the accepted answer as it answers the question directly and gives a solution instead of just theory. – supersan Jul 06 '19 at 14:41
  • 1
    Justa note (atleast on older versions) if NOW < UTC_TIMESTAMP then the result is NULL. so you have to an if statement and check that first, then reverse the comparison – WiR3D Feb 10 '23 at 12:18
18

To get Current timezone of the mysql you can do following things:

 SELECT @@system_time_zone;   # from this you can get the system timezone 
 SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone) # This will give you time zone if system timezone is different from global timezone

Now if you want to change the mysql timezone then:

 SET GLOBAL time_zone = '+00:00';   # this will set mysql timezone in UTC
 SET @@session.time_zone = "+00:00";  # by this you can chnage the timezone only for your particular session 
Amit Shah
  • 7,771
  • 5
  • 39
  • 55
Abhinav bhardwaj
  • 2,657
  • 25
  • 21
16

To anyone come to find timezone of mysql db.

With this query you can get current timezone :

mysql> SELECT @@system_time_zone as tz;
+-------+
|  tz   |
+-------+
|  CET  |
+-------+

ttrasn
  • 4,322
  • 4
  • 26
  • 43
  • My result: `St?edn? Evropa (b??n? ?as)`. Such value is unacceptable. – mikiqex Nov 30 '22 at 18:16
  • @mikiqex I've no idea about the problem, It should be a conflict on your main MySQL database or maybe from your system. I suggest you try it in another system – ttrasn Dec 01 '22 at 08:30
  • @mikiqex maybe use `SET NAMES utf8` to fix your display – myselfhimself Apr 14 '23 at 08:03
  • @myselfhimself Thanks, but didn't help: ```St�edn� Evropa (b�n� �as)```. I tried several other charsets and collations, with no luck. It may be corrupted during initial setup or it doesn't take it correctly from the system. – mikiqex Apr 14 '23 at 09:01
15

If you need the GMT difference as an integer:

SELECT EXTRACT(HOUR FROM (TIMEDIFF(NOW(), UTC_TIMESTAMP))) AS `timezone`
Luca Fagioli
  • 12,722
  • 5
  • 59
  • 57
  • Wrong. Doesn't work for timezones like IRST that are not exact integer hours. (it is +3:30) https://www.timeanddate.com/time/zones/irst – Aidin Nov 11 '21 at 16:52
5

The command mention in the description returns "SYSTEM" which indicated it takes the timezone of the server. Which is not useful for our query.

Following query will help to understand the timezone

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) as GMT_TIME_DIFF;

Above query will give you the time interval with respect to Coordinated Universal Time(UTC). So you can easily analyze the timezone. if the database time zone is IST the output will be 5:30

UTC_TIMESTAMP

In MySQL, the UTC_TIMESTAMP returns the current UTC date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS.uuuuuu format depending on the usage of the function i.e. in a string or numeric context.

NOW()

NOW() function. MySQL NOW() returns the value of current date and time in 'YYYY-MM-DD HH:MM:SS' format or YYYYMMDDHHMMSS.uuuuuu format depending on the context (numeric or string) of the function. CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(), LOCALTIME, LOCALTIME(), LOCALTIMESTAMP, LOCALTIMESTAMP() are synonyms of NOW().

Amitesh Bharti
  • 14,264
  • 6
  • 62
  • 62
4

Check out MySQL Server Time Zone Support and the system_time_zone system variable. Does that help?

Toddius Zho
  • 624
  • 6
  • 12
Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • @user can you please spell out in your question what info you are exactly looking for (the server's time zone? The client's?) and what tools are at your disposal? You mention PHP. Can you access the command line? – Pekka May 29 '10 at 08:17
  • 5
    @user also, I find you're coming across as a bit of a dick downvoting answers from people who are trying to be helpful, and not exactly wrong. I don't mind the vote nor the loss of point, but your attitude is not exactly encouraging to look any further for a solution. – Pekka May 29 '10 at 08:22
  • The tools are PHP and MySQL,I want to get valid information like `GMT+8` or something like that,a value between `-12~+12`,but just not `SYSTEM`.I'll upvote and ticket it as accepted once the answer is correct,but sorry will downvote if not the case. – user198729 May 29 '10 at 08:26
  • 3
    @user as I said, your attitude is not motivating me to research for further answers for you, especially in light of the meagre information you provide. Sorry. – Pekka May 29 '10 at 08:30
  • 3
    @user198729: Wow, lose the attitude. Pekka's the kind of guy to really help people out. If courtesy alone isn't sufficient to motivate you, try self-interest. – T.J. Crowder May 29 '10 at 08:41
  • 2
    Just my thoughts: I wouldn't have taken offense if user had done the same thing to my post. I mean, deadline pressure or frustration does add some rough edges around people, but I think we should allow it to some extent. Maybe I am too forgiving :| – Senthil May 29 '10 at 08:47
  • @user198729: I've just edited his answer, you should be able to do so now. (Not that, again, the reputation was the point for him.) – T.J. Crowder May 29 '10 at 08:58
  • Cheers @T.J. @user, T.J. already posted what I would have looked for next, the PHP functions to get the current time zone. That should do. Another way to get the correct zone would be to query it on the (Linux) command line using `date`: http://www.linuxquestions.org/questions/linux-general-1/how-to-get-time-zone-information-from-the-system-230064/ if you can access that programmatically. – Pekka May 29 '10 at 09:01
2

Use LPAD(TIME_FORMAT(TIMEDIFF(NOW(), UTC_TIMESTAMP),’%H:%i’),6,’+') to get a value in MySQL's timezone format that you can conveniently use with CONVERT_TZ(). Note that the timezone offset you get is only valid at the moment in time where the expression is evaluated since the offset may change over time if you have daylight savings time. Yet the expression is useful together with NOW() to store the offset with the local time, which disambiguates what NOW() yields. (In DST timezones, NOW() jumps back one hour once a year, thus has some duplicate values for distinct points in time).

Kirby
  • 15,127
  • 10
  • 89
  • 104
rtc
  • 69
  • 5
  • Typo in single quotes. `LPAD(TIME_FORMAT(TIMEDIFF(NOW(), UTC_TIMESTAMP), '%H:%i'), 6, '+')` – Tigrov Jul 18 '23 at 07:44
1

It may be

select timediff(current_time(),utc_time())

You won't get the timezone value directly this way.

@@global.time_zone cannot be used as it is a variable, and it returns the value 'SYSTEM'.

If you need to use your query in a session with a changed timezone by using session SET TIME_ZONE =, then you will get that with @@session.time_zone. If you query @@global.time_zone, then you get 'SYSTEM'.

If you try datediff, date_sub, or timediff with now() and utc_time(), then you'll probably run into conversion issues.

But the things suggested above will probably work at least with some server versions. My version is 5.5.43-37 and is a hosted solution.

Kirby
  • 15,127
  • 10
  • 89
  • 104
dwaid
  • 41
  • 1
1

My PHP framework uses

SET LOCAL time_zone='Whatever'

on after connect, where 'Whatever' == date_default_timezone_get()

Not my solution, but this ensures SYSTEM timezone of MySQL server is always the same as PHP's one

So, yes, PHP is strongly envolved and can affect it

vladkras
  • 16,483
  • 4
  • 45
  • 55
1

You can try the following:

select sec_to_time(TIME_TO_SEC( curtime()) + 48000);

Here you can specify your time difference as seconds

Osh Mansor
  • 1,232
  • 2
  • 20
  • 42
Bala Kayan
  • 27
  • 1
  • 3
    you should not add and subtract offsets. with daylight saying rules etc it is a minefield – eweb Apr 02 '20 at 15:51
1

To get the current time according to your timezone, you can use the following (in my case its '+5:30')

select DATE_FORMAT(convert_tz(now(),@@session.time_zone,'+05:30') ,'%Y-%m-%d')

Sanjoy Kanrar
  • 899
  • 8
  • 11
1

Based on Timos answer. Atleast on older version of mysql if your current timezone is lower than UTC then his solution returns NULL.

SELECT 
    IF(NOW() >= UTC_TIMESTAMP,
        CONCAT('+', SUBSTRING_INDEX(TIMEDIFF(NOW(), UTC_TIMESTAMP), ':', 2)),
        CONCAT('-', SUBSTRING_INDEX(TIMEDIFF(UTC_TIMESTAMP, NOW()), ':', 2))
    ) AS offset;

this returns (based on your timezone)

+02:00
-01:00
WiR3D
  • 1,465
  • 20
  • 23
0

You just need to restart mysqld after altering timezone of System..

The Global time zone of MySQL takes timezone of System. When you change any such attribute of system, you just need a restart of Mysqld.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
  • after changing the timezone on the OS, mysql inserts will use the new timezone but select now(); and select current_timestamp; commands will still use the old timezone. To sync up all these, mysql service must be restarted. – Manoj Kumar G May 05 '18 at 19:28
0

Insert a dummy record into one of your databases that has a timestamp Select that record and get value of timestamp. Delete that record. Gets for sure the timezone that the server is using to write data and ignores PHP timezones.

alee
  • 53
  • 2
0

It is not a direct answer to this question but this blog post provides valuable information on the subject:

https://danuka-praneeth.medium.com/guide-to-time-zones-conversion-between-zones-and-storing-in-mysql-da4fc4350cd9.

Quote from the blog post:

In MySQL5+, TIMESTAMP values are converted from the session time zone to UTC for storage, and from UTC to the session time zone for retrieval. But DATETIME does not do any conversion.

e-mre
  • 3,305
  • 3
  • 30
  • 46
-3

Try using the following code:

//ASP CLASSIC
Set dbdate = Server.CreateObject("ADODB.Recordset")
dbdate.ActiveConnection = MM_connection
dbdate.Source = "SELECT NOW() AS currentserverdate "
dbdate.Open()
currentdate = dbdate.Fields("currentserverdate").Value
response.Write("Server Time is "&currentdate)
dbdate.Close()
Set dbdate = Nothing
Hadi
  • 36,233
  • 13
  • 65
  • 124