MySQL Time Zones - mysql

Is there an exhaustive list of MySQL Time Zones?
It seems that the valid values for time_zone in MySQL settings are dependent on the host Operating System but I have been unable to find a list of possible values.
I need the time to show Calgary local time.

By default, (at least on Debian-based installations) no time zone data is loaded into MySQL. If you want to test if they are loaded, try executing:
SELECT CONVERT_TZ('2012-06-07 12:00:00', 'GMT', 'America/New_York');
If it returns a DATETIME (in this case 2012-06-07 08:00:00), you have time zones loaded. If it returns NULL, they aren't. When not loaded, you are limited to converting using offsets (e.g. +10:00 or -6:00).
This should work fine in many cases, but there are times when it is better to use named time zones, like for not worrying about daylight savings time. Executing the following command loads the time zone data from the system (Unix-only. I'm not sure what the equivalent Windows command would be):
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
If you need to continually rely on MySQL time zones, the above command should be executed every time the system time zone is updated. You could also just add it to a weekly or monthly cron job to do it for you automatically.
Then, to view a list of time zones, just do the following:
USE mysql;
SELECT * FROM `time_zone_name`;
Note, the time zone info takes up about 5 MB in MySQL. If you ever want to un-load the timezone info, just execute the following and restart MySQL:
TRUNCATE `time_zone` ;
TRUNCATE `time_zone_leap_second` ;
TRUNCATE `time_zone_name` ;
TRUNCATE `time_zone_transition` ;
TRUNCATE `time_zone_transition_type` ;
Do not DROP these tables or bad things will happen.
Edit:
Based on a user comment below, if you want to have the timezones automatically updated when you update the system, you first need to allow root to log in without being prompted for a password.
MySQL >= 5.6.6
Execute the following [source]:
mysql_config_editor set --login-path=client --host=localhost --user=root --password
MySQL < 5.6.6
Create a ~/.my.cnf file (if it doesn't exist yet) and add the following:
[client]
user=root
password=yourMysqlRootPW
Then execute chmod 600 ~/.my.cnf to make sure nobody else can read it.
Update script
Add the following script to crontab to be executed once per day:
#!/bin/bash
# Find if there are any timezone files that have been modified in the last 24
# hours and do not have ".tab" in the name (since these are not timezone files)
if [ `find /usr/share/zoneinfo -mtime -1 | grep -v '\.tab' | wc -l` -gt 0 ]; then
echo "Updating MySQL timezone info"
# Note, suppressing STDERR here because of the .tab files above
# that cause warnings.
mysql_tzinfo_to_sql /usr/share/zoneinfo 2>/dev/null | mysql -u root mysql
echo "Done!\n"
fi
Remove the echo lines if you don't want any output.
Note: This is (mostly) untested. Let me know if you have any issues and I'll update this answer.

From the MySQL 5.7 documentation (emphasis mine):
timezone values can be given in several formats, none of which are
case sensitive:
The value 'SYSTEM' indicates that the time zone should be the same as
the system time zone.
The value can be given as a string indicating an offset from UTC, such
as '+10:00' or '-6:00'.
The value can be given as a named time zone, such as
'Europe/Helsinki', 'US/Eastern', or 'MET'. Named time zones can be
used only if the time zone information tables in the mysql database
have been created and populated.
It should be noted that the MySQL timezone variable's default setting is SYSTEM at MySQL startup. The SYSTEM value is obtained from an operating system setting (e.g. from the file that is referenced by the symlink /etc/localtime)
MySQL's default timezone variable can be initialised to a different value at start-up by providing the following command line option:
--default-time-zone=timezone
Alternatively, if you are supplying the value in an options file, you should use the following syntax to set the variable:
--default-time-zone='timezone'
If you are a MySQL SUPER user, you can set the SYSTEM time_zone variable at runtime from the MYSQL> prompt using the following syntax:
SET GLOBAL time_zone=timezone;
MySQL also supports individual SESSION timezone values which defaults to the GLOBAL time_zone environment variable value. To change the session timezone value during a SESSION, use the following syntax:
SET time_zone=timezone;
In order to interrogate the existing MYSQL timezone setting values, you can execute the following SQL to obtain these values:
SELECT ##global.time_zone, ##session.time_zone;
For what it's worth, I simply googled mysql time_zone configuration valid values and looked at the first result.

You can run this query to get a complete list of the timezones MySQL supports:
SELECT Name
FROM mysql.time_zone_name
ORDER BY Name
(Found on this page: https://www.plumislandmedia.net/mysql/time-zones-mysql/)

An exhaustive list of timezones can be downloaded from MySQL's website as database tables that get imported into MySQL server.
For Calgary time you can specify UTC offsets as
set time_zone = '-6:00';

It should be noted that the MySQL timezone variable's default setting is SYSTEM at MySQL startup. The SYSTEM value is obtained from the operating system's GLOBAL time_zone environment variable.
MySQL's default timezone variable can be initialised to a different value at start-up by providing the following command line option:
--default-time-zone=timezone
Alternatively, if you are supplying the value in an options file, you should use the following syntax to set the variable:
--default-time-zone='timezone'
If you are a MySQL SUPER user, you can set the SYSTEM time_zone variable at runtime from the MYSQL> prompt using the following syntax:
SET GLOBAL time_zone=timezone;
MySQL also supports individual SESSION timezone values which defaults to the GLOBAL time_zone environment variable value. To change the session timezone value during a SESSION, use the following syntax:
SET time_zone=timezone;
In order to interrogate the existing MYSQL timezone setting values, you can execute the following SQL to obtain these values:
SELECT ##global.time_zone, ##session.time_zone;

Related

Howto activate named time zones

I want to automate the installation and configuration of a mysql server using azure cli.
The installation works well using azure mysql server create, however the configuration using azure mysql server configuration set -n time_zone --value Europe/Paris fails due to the following error:
Deployment failed. Correlation ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. The value 'Europe/Paris' for configuration 'time_zone' is not valid. The allowed values are '[+|-][0]{0,1}[0-9]:[0-5][0-9]|[+|-][1][0-2]:[0-5][0-9]|SYSTEM'.
As I read in the mysql docs I could enable named time zones executing the following sql SET GLOBAL time_zone = timezone;, but unfortunately my user would need super privilege for this to succeed and this is impossible in azure.
The other approach would be to run mysql_tzinfo_to_sql but this is not available using azure cli.
Is there any other way to activate named time zones?
From the Azure DB for MySQL documentation:
Populating the time zone tables
The time zone tables on your server can be populated by calling the mysql.az_load_timezone stored procedure from a tool like the MySQL command line or MySQL Workbench.
CALL mysql.az_load_timezone();
Also, in this doc (you linked to in your question):
Upon initial deployment, an Azure for MySQL server includes systems tables for time zone information, but these tables are not populated. The time zone tables can be populated by calling the mysql.az_load_timezone stored procedure from a tool like the MySQL command line or MySQL Workbench.
According to Error message the format should be one of these three:
[+|-][0]{0,1}[0-9]:[0-5][0-9]
eg. -04:30
or
[+|-][1][0-2]:[0-5][0-9]
e.g -12:00
or
SYSTEM
So have you tried doing it with quotes?
azure mysql server configuration set -n time_zone --value
"Europe/Paris"
CALL mysql.az_load_timezone();
Call this stored procedure from your session on the server,
If you are running the mysql.az_load_timezone command from MySQL Workbench, you may need to turn off safe update mode first using SET SQL_SAFE_UPDATES=0 or in Preferences->SQL Editor->Safe Updates(), and back to connect to your mysql server.

Why timestamp in MySQL JDBC have to be corrected with 'GMT-6:00'?

I have a table contains a regular datetime typed column, and when selecting mysql command line returns the correct result:
but when it comes to JDBC, it'll return 2020-02-03 08:00:00. I have to use TimeZone.setDefault(TimeZone.getTimeZone("GMT-6:00") to regulate it.
On my server, the time zone related options are:
But seems the result JDBC driver returns is neither in my current time zone, nor the UTC. Is this because of something wrong on my MySQL server...?
Currently I'm using mysql:latest on Docker Windows and mysql:mysql-connector-java:8.0.19, the TZ environment of Docker container has been set to my local time zone.
Many thanks.

The date and time takes the timezone of the server where it is hosted rather then where the server is currently used in particular location

Suppose I am located in India and my Mysql database server is stored in the Oregon server.So when i am trying to track datetime (i.e. now()) whenever i perform Insert or update operation of the data in the table .It always take the time zone of the Oregon server
Can i use the system timezone where my Mysql server is being hosted?
Presently I am using a function whenever i use to display datetime on front-end
CREATE DEFINER=`root`#`localhost` FUNCTION `FnTimeZone`(P_date datetime) RETURNS varchar(100) CHARSET latin1
BEGIN
declare returnDate varchar(100);
Select convert_tz(P_date,'+00:00','+00:00') into returnDate;
RETURN returnDate;
END
Can you please help me find better solution?
Thanks
There are a number of ways you can configure the timezone mysql uses. Mysql documentation on MySQL Server Time Zone Support lists all these options for you:
The system time zone. When the server starts, it attempts to determine the time zone of the host machine and uses it to set the
system_time_zone system variable. The value does not change
thereafter.
You can set the system time zone for MySQL Server at startup with the --timezone=timezone_name option to mysqld_safe. You can also set
it by setting the TZ environment variable before you start mysqld. The
permissible values for --timezone or TZ are system dependent. Consult
your operating system documentation to see what values are acceptable.
The server's current time zone. The global time_zone system variable indicates the time zone the server currently is operating in.
The initial value for time_zone is 'SYSTEM', which indicates that the
server time zone is the same as the system time zone.
The initial global server time zone value can be specified explicitly at startup with the --default-time-zone=timezone option on
the command line, or you can use the following line in an option file:
default-time-zone='timezone'
If you have the SUPER privilege, you can set the global server time zone value at runtime with this statement:
mysql> SET GLOBAL time_zone = timezone;
Per-connection time zones. Each client that connects has its own time zone setting, given by the session time_zone variable. Initially,
the session variable takes its value from the global time_zone
variable, but the client can change its own time zone with this
statement:
mysql> SET time_zone = timezone;

How to call a procedure on every time mysql connection created on amazon RDS

I want to change timezone for amazon RDS for every session.
RDS timezone by default is UTC.
I want to change it to Asia/Calcutta.
To change timezone for specific session I have defined procedure
DELIMITER |
CREATE PROCEDURE mysql.store_time_zone ()
IF NOT (POSITION('rdsadmin#' IN CURRENT_USER()) = 1) THEN
SET SESSION time_zone = '+5:30';
END IF
|
DELIMITER ;
Now I donot know how should I call it every time new connection/Session is created.
I have taken reference from given link. I am not able to run
rds-modify-db-parameter-group PARAMGROUP --parameters "name=init_connect, value='CALL mysql.store_time_zone', method=immediate"
It gives error
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rds-modify-db-parameter-group PARAMGROUP --parameters "name=init_connect, value=' at line 1
https://stackoverflow.com/a/15198369/3551179
Thanks in advance.
You are on the right track, but you have misunderstood one step, due to ambiguous phrasing in the other answer:
Connect to your instance, and run the following command
So, you're essentially doing this:
mysql> rds-modify-db-parameter-group ...
But you should instead be doing this:
$ rds-modify-db-parameter-group ...
It's not a MySQL statement, it's a shell command. RDS instances do not have shell access, so you need a different machine to run this command on. Typically, this might be an EC2 instance, so I assume that's what the other manager's author meant by "your instance," but it could be any machine that has the RDS command line interface tools installed.
You can also do this from the RDS Console.
Note also that you could also do this a bit more concisely, avoiding the stored procedure altogether and even the test for rdsadmin, by setting init_connect to:
SET ##time_zone = '+5:30'
The rdsadmin user should be immune to init_connect because it has the SUPER privilege.
The content of init_connect is not executed for users that have the SUPER privilege. This is done so that an erroneous value for init_connect does not prevent all clients from connecting. For example, the value might contain a statement that has a syntax error, thus causing client connections to fail. Not executing init_connect for users that have the SUPER privilege enables them to open a connection and fix the init_connect value.
http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_init_connect
If you'd rather test for rdsadmin anyway...
SET ##time_zone = CASE
WHEN CURRENT_USER() LIKE 'rdsadmin#%' THEN ##time_zone
ELSE '+5:30' END
Setting a variable to the same variable leaves the value unchanged.
Note ##time_zone and SESSION time_zone are equivalent.

MySQL timezone change?

How do I change my timezone which is currently in UTC to GMT +1, what is the correct line and do i just enter it in phpMyAdmin SQL execution?
My host just gave me this link http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html and went off so I'm kinda lost thanks
The easiest way to do this, as noted by Umar is, for example
mysql> SET GLOBAL time_zone = 'America/New_York';
Using the named timezone is important for timezone that has a daylights saving adjustment. However, for some linux builds you may get the following response:
#1298 - Unknown or incorrect time zone
If you're seeing this, you may need to run a tzinfo_to_sql translation... it's easy to do, but not obvious. From the linux command line type in:
mysql_tzinfo_to_sql /usr/share/zoneinfo/|mysql -u root mysql -p
Provide your root password (MySQL root, not Linux root) and it will load any definitions in your zoneinfo into mysql. You can then go back and run your
mysql> SET GLOBAL time_zone = timezone;
issue the command:
SET time_zone = 'America/New_York';
(Or whatever time zone GMT+1 is.: http://www.php.net/manual/en/timezones.php)
This is the command to set the MySQL timezone for an individual client, assuming that your clients are spread accross multiple time zones.
This command should be executed before every SQL command involving dates. If your queries go thru a class, then this is easy to implement.
While Bryon's answer is helpful, I'd just add that his link is for PHP timezone names, which are not the same as MySQL timezone names.
If you want to set your timezone for an individual session to GMT+1 (UTC+1 to be precise) just use the string '+01:00' in that command. I.e.:
SET time_zone = '+01:00';
To see what timezone your MySQL session is using, just execute this:
SELECT ##global.time_zone, ##session.time_zone;
This is a great reference with more details: MySQL 5.5 Reference on Time Zones
Here is how to synchronize PHP (>=5.3) and MySQL timezones per session and user settings. Put this where it runs when you need set and synchronized timezones.
date_default_timezone_set($my_timezone);
$n = new \DateTime();
$h = $n->getOffset()/3600;
$i = 60*($h-floor($h));
$offset = sprintf('%+d:%02d', $h, $i);
$this->db->query("SET time_zone='$offset'");
Where $my_timezone is one in the list of PHP timezones: http://www.php.net/manual/en/timezones.php
The PHP timezone has to be converted into the hour and minute offset for MySQL. That's what lines 1-4 do.
If you have the SUPER privilege, you can set the global server time zone value at runtime with this statement:
mysql> SET GLOBAL time_zone = timezone;
If SET time_zone or SET GLOBAL time_zone does not work, you can change as below:
Change timezone system, example: ubuntu... $ sudo dpkg-reconfigure
tzdata
Restart the server or you can restart apache2 and mysql
(/etc/init.d/mysql restart)
This works fine
<?php
$con=mysqli_connect("localhost","my_user","my_password","my_db");
$con->query("SET GLOBAL time_zone = 'Asia/Calcutta'");
$con->query("SET time_zone = '+05:30'");
$con->query("SET ##session.time_zone = '+05:30'");
?>