converting datetime mysql with timezone from same table - mysql

I have a table with the following columns (simplified): openingtime | timezone
This tables holds opening times. The datetime is in the timezone my server is in, timezone is the timezone of the location the opening time is for. I would like to query the datetime column ending up with the local time.
Example data:
2022-07-08 11:00:00 | Europe/London
My server is in Europe/Paris so the expected output would be 2022-07-08 10:00:00
The following only gives my NULL as results:
SELECT CONVERT_TZ(openingtime, 'Europe/Paris', timezone)
FROM openingtimes

To use CONVERT_TZ() you need to install the time-zone tables otherwise MySQL returns NULL.
To load time zone:
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
After time zone loaded:
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.25 |
+-----------+
1 row in set (0.00 sec)
mysql> SELECT CONVERT_TZ('2022-07-08 11:00:00', 'Europe/London','GMT') ;
+----------------------------------------------------------+
| CONVERT_TZ('2022-07-08 11:00:00', 'Europe/London','GMT') |
+----------------------------------------------------------+
| 2022-07-08 10:00:00 |
+----------------------------------------------------------+
1 row in set (0.00 sec)

Related

MySQL : STR_TO_DATE function giving null on correct output with format

I'm trying to convert string to date in mysql. Inspite of giving correct string and format specifier, mysql is giving NULL output with warning message as Incorrect datetime value: 'XXXXX' for function str_to_date although it is working for full date string.
mysql logs
mysql> SELECT STR_TO_DATE('2018/06', '%Y/%m');
+---------------------------------+
| STR_TO_DATE('2018/06', '%Y/%m') |
+---------------------------------+
| NULL |
+---------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SELECT STR_TO_DATE('2018/06/01', '%Y/%m/%d'); +---------------------------------------+
| STR_TO_DATE('2018/06/01', '%Y/%m/%d') |
+---------------------------------------+
| 2018-06-01 |
+---------------------------------------+
1 row in set (0.00 sec)
debug info
MySQL version - 5.7.21 MySQL Community Server (GPL)
mysql> show warnings;
+---------+------+--------------------------------------------------------------+
| Level | Code | Message |
+---------+------+--------------------------------------------------------------+
| Warning | 1411 | Incorrect datetime value: '2018/06' for function str_to_date |
+---------+------+--------------------------------------------------------------+
1 row in set (0.00 sec)
Requirement
I want to parse month and year from above date string.
For fulfilling my requirement, I'm using following workaround -
mysql> SELECT YEAR(STR_TO_DATE(CONCAT('2018/06', '/01'), '%Y/%m/%d'));
+---------------------------------------------------------+
| YEAR(STR_TO_DATE(CONCAT('2018/06', '/01'), '%Y/%m/%d')) |
+---------------------------------------------------------+
| 2018 |
+---------------------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT MONTH(STR_TO_DATE(CONCAT('2018/06', '/01'), '%Y/%m/%d'));
+----------------------------------------------------------+
| MONTH(STR_TO_DATE(CONCAT('2018/06', '/01'), '%Y/%m/%d')) |
+----------------------------------------------------------+
| 6 |
+----------------------------------------------------------+
1 row in set (0.00 sec)
You can use DATE_FORMAT function in mysql
SELECT DATE_FORMAT('2018/06/01', '%Y-%m')
NB: The date string should be in any valid MYSQL DATE FORMAT(Year month day)
If your date string is always in 'yyyy/mm' format
instead of using date function you can use substring OR substring_index function in MYSQL.
select substring("2018/06",1,4) AS year, substring("2018/06",6,2) as month
OR
select substring_index("2018/06","/",1) AS year, substring_index("2018/06","/",-1) as month

How to convert a Mysql timestamp to sysdate(6) format(with milliseconds)?

I am new to postgres and I have been working on Mysql for quiet sometimes. I need to migrate content from Mysql table to Postgres table.
My Postgres table is like this:
Column | Type | Modifiers
--------------------------------+-----------------------------+------------------------------------------------------------------------------------------------
id | integer |
created_at | timestamp without time zone | not null default timezone('UTC'::text, now())
updated_at | timestamp without time zone | not null default timezone('UTC'::text, now())
key_classification | character varying(2000) | not null
I am inserting created_at and updated_at value from mysql table which is in the form "2014-09-04 23:40:14".
when I insert a row into my postgres table the default timestamp is in the form "2016-01-22 17:44:53.342757" which inclues millisecond in the timestamp.
Now I need to add the millisecond to the mysql timestamp format to match the postgres table format.
Please help to add the millisecond into the timestamp.
Thanks in advance!
Morning Arunraj
I hope this helps ?
I'm running Mysql/MariaDB
MariaDB [(none)]> SHOW VARIABLES LIKE "%version%";
+-------------------------+-----------------+
| Variable_name | Value |
+-------------------------+-----------------+
| innodb_version | 5.6.25-73.1 |
| protocol_version | 10 |
| slave_type_conversions | |
| version | 10.0.21-MariaDB |
| version_comment | MariaDB Server |
| version_compile_machine | x86_64 |
| version_compile_os | Linux |
| version_malloc_library | system |
+-------------------------+-----------------+
8 rows in set (0.00 sec)
And I'm referencing 11.3.6 Fractional Seconds in Time Values
Which is mysql version 5.7
To run the example
As mysql Admin
mysql -u USERNAME -p
CREATE USER 'test'#'localhost' IDENTIFIED BY 'test';
CREATE DATABASE test;
GRANT ALL ON test.* TO 'test'#'localhost';
Quit and then login as test
mysql -u test -p
The password is test
Then
CREATE TABLE test.td6(ts6 timestamp(6));
INSERT INTO test.td6 VALUES ('2016-01-22 17:44:53.342757');
The inserted value is the timestamp format you wanted to insert into mysql.
All the best

What is the impact of system time zone of RHEL6 server in MySQL replication?

We have a master server in EST time zone while slave is configured to follow IST time zone but mysql on slave is configured with default_time_zone=EST5EDT just to make both DB instances follow same timezone , but If I execute
mysql > Select now();
on both servers I am getting same value , in contrast while I insert values in master instance using now() it insert values in EST on master and in IST on slave which is causing data discrepancy in master and slave as far for data columns.
Below is the test I performed
Master : (Having EST as system timezone)
mysql> insert into test_timezone values (1,now());
Query OK, 1 row affected (0.00 sec)
mysql> insert into test_timezone values (2,now());
Query OK, 1 row affected (0.00 sec)
mysql> insert into test_timezone values (3,now());
Query OK, 1 row affected (0.00 sec)
mysql> select * from test_timezone;
+------+---------------------+
| id | date_tz |
+------+---------------------+
| 1 | 2015-02-02 02:53:46 |
| 2 | 2015-02-02 02:53:50 |
| 3 | 2015-02-02 02:53:54 |
+------+---------------------+
Slave : (Having IST as system timezone but mysql default timezone is EST5EDT)
mysql> select * from test_timezone;
+------+---------------------+
| id | date_tz |
+------+---------------------+
| 1 | 2015-02-02 13:23:46 |
| 2 | 2015-02-02 13:23:50 |
| 3 | 2015-02-02 13:23:54 |
+------+---------------------+
3 rows in set (0.00 sec)
So what needs to be done to get same time on master and slave while inserting/updating data ?
MySQL is dependent on system time zone.
default-time-zone='TIMEZONE'
If this variable in not configured in my.cnf then MySQL will use system time zone to save and display data. If you want to have same time values in master and slave then ideal way is to configure
default-time-zone='TIMEZONE'
Above variable in master and slave this will have precedence over system time zone and you will have same time values in master and slaves.
If you don't find your required time zone in MySQL, please follow below link to populate time zones in MySQL database
https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

Mysql: How to diagnosis and correct wrong timezone

In my server, I have the following from the command line:
]$ date
Fri Sep 16 13:47:02 JST 2011
Which is correct.
in mysql, I have the following:
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2011-09-16 04:50:21 |
+---------------------+
1 row in set (0.00 sec)
mysql> SELECT ##global.time_zone, ##session.time_zone;
+--------------------+---------------------+
| ##global.time_zone | ##session.time_zone |
+--------------------+---------------------+
| SYSTEM | SYSTEM |
+--------------------+---------------------+
1 row in set (0.00 sec)
So, it is set to the system time, but then why is not showing the same time?
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.
That's it.
Your queries are returning the values in UTC but from the command line output your system is in JST. Since the variables are returning SYSTEM I would suggest that perhaps your configuration has identified system as UTC. Check out your my.cnf as suggested here How do I make MySQL's NOW() and CURDATE() functions use UTC?.

Custom time in MYSQL on update

I have a table with some rows and within them there is a definition that goes like this:
`metric_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
So what i actually want it to do is to automatically insert a timestamp when inserting data into that table. And it does. But what I need is to write a GMT based time into that field (current server time is like GMT+2).
Is there a way to say to MYSQL to do such thing?
If your server time and timezone settings are configured correctly, then internally all times stored in TIMESTAMP columns are converted to GMT (since that's what Unix timestamp mandates). They're converted back to your session timezone when you retrieve this data. If you want it presented in GMT timezone, you need to do conversion while retrieving data not while inserting.
See the console dump below for example. You can run these commands yourself to check.
mysql> use test;
Database changed
mysql> -- let's create a table we'll be working with
mysql> CREATE TABLE tsTable (
-> ID INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-> ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
-> );
Query OK, 0 rows affected (0.08 sec)
mysql> -- let's check current time as well as timezone settings
mysql> SELECT CURTIME(),##global.time_zone, ##session.time_zone;
+-----------+--------------------+---------------------+
| CURTIME() | ##global.time_zone | ##session.time_zone |
+-----------+--------------------+---------------------+
| 16:25:51 | SYSTEM | +02:00 |
+-----------+--------------------+---------------------+
1 row in set (0.05 sec)
mysql> -- inserting empty row to table to trigger auto timestamp
mysql> INSERT INTO tsTable VALUES (null,null);
Query OK, 1 row affected (0.00 sec)
mysql> -- looks like the time in my local timezone is stored in table
mysql> SELECT * FROM tsTable;
+----+---------------------+
| ID | ts |
+----+---------------------+
| 1 | 2011-07-28 16:26:25 |
+----+---------------------+
1 row in set (0.00 sec)
mysql> -- switching to GMT
mysql> SET SESSION time_zone = '+0:00';
Query OK, 0 rows affected (0.00 sec)
mysql> -- check current time and timezone settings again
mysql> SELECT CURTIME(),##global.time_zone, ##session.time_zone;
+-----------+--------------------+---------------------+
| CURTIME() | ##global.time_zone | ##session.time_zone |
+-----------+--------------------+---------------------+
| 14:27:53 | SYSTEM | +00:00 |
+-----------+--------------------+---------------------+
1 row in set (0.00 sec)
mysql> -- note: CURTIME() returns time two hours 'earlier' than before
mysql> -- let's see what's stored in the table again
mysql> SELECT * FROM tsTable;
+----+---------------------+
| ID | ts |
+----+---------------------+
| 1 | 2011-07-28 14:26:25 |
+----+---------------------+
1 row in set (0.00 sec)
mysql> -- TIMESTAMP is two hours 'earlier' than before too! Magick!
INSERT INTO table_name(column1, metric_update_time) VALUES('dummy', CONVERT_TZ(CURRENT_TIMESTAMP,'+02:00','+03:00');
This will convert the inserted timestamp from GMT+2 to GMT+3.