Convert local TIME_STAMP to UTC time - mysql

I have two tables with time stamps
TABLE1 with TIME_STAMP in local time
TABLE2 with TIME_STAMP in UTC
I need to do something like
select count(*) from TABLE1 where TIME_STAMP > TABLE2.TIME_STAMP
The problem is that this app will be deployed in multiple time zones so I cannot use the following
SELECT CONVERT_TZ(TABLE2.TIME_STAMP,'EST','UTC')
because 'EST' can be any time zone.
Is there a way of getting local time zone code and substituting it as second argument?
Or is there a better and more direct approach to solving my issue?
NOTE: Both TABLE1 and TABLE2 TIME_STAMPS have to remain as local and UTC respectively as they are externals that I have no control over...

Here is the solution I implemented:
This will convert NOW from local timezone to UTC
SELECT CONVERT_TZ( NOW(), ##session.time_zone, '+00:00' )
This will convert any given TIMESTAMP string from local timezone to UTC
SELECT CONVERT_TZ( "2012-02-14 16:44:36", ##session.time_zone, '+00:00' )

Related

UTC to America/New_York time zone using MySQL

I am storing a date in UTC timezone inside my table but my need is to export a CSV file by converting a date from UTC to America/New_York time zone.
I have tried with CONVERT_TZ MySQL function, but it's giving null.
How I can convert a date from UTC to America/New_York time zone using only MySQL and not using PHP?
You have to load the timezone table.
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p password
If you do not have superuser access, you can skip friendly timezone names and specify the hours.
CONVERT_TZ(date,'+00:00','-07:00')
The reason behind you are getting null result once you are using CONVERT_TZ MySQL function is that TZ time zone table have not been setup.
You can check that time zone table is set up or not.
select * from mysql.time_zone;
If it's giving null values then you need:
insert time zone in MySql if you want to use CONVERT_TZ MySQL function to convert a date from UTC to America New_Yark time zone.
You can run below query without update time_zone table.
SELECT DATE_SUB( order_date, INTERVAL 5 HOUR ) as OrderDate
FROM TABLE_NAME
With date format:
SELECT DATE_FORMAT( DATE_SUB( order_date, INTERVAL 5 HOUR ) , '%Y-%m-%d %h.%i.%s %p' ) as OrderDate
FROM TABLE_NAME
Please have a look similar question.
MySQL CONVERT_TZ()
It will help you in "How to insert timezone in MySql".

MySql timestamp rounding then reformatting in human readable format

I have the following query from Group OHLC-Stockmarket Data into multiple timeframes - Mysql.
SELECT
FLOOR(MIN(`timestamp`)/"+period+")*"+period+" AS timestamp,
SUM(amount) AS volume,
SUM(price*amount)/sum(amount) AS wavg_price,
SUBSTRING_INDEX(MIN(CONCAT(`timestamp`, '_', price)), '_', -1) AS `open`,
MAX(price) AS high,
MIN(price) AS low,
SUBSTRING_INDEX(MAX(CONCAT(`timestamp`, '_', price)), '_', -1) AS `close`
FROM transactions_history -- this table has 3 columns (timestamp, amount, price)
GROUP BY FLOOR(`timestamp`/"+period+")
ORDER BY timestamp
In my select statement, FLOOR(MIN(timestamp)/"+period+")*"+period+" AS timestamp,
I am trying to understand what it is doing. and
I need to convert this back to a mysql date/time Y-M-D H:i:s string or a UTC timestamp for parsing via javascript.
Let's assume that +period+ is 86400 (The number of seconds in a day)
Let's assume that the timestamp is '2015-12-08 20:58:58'
From what I can see, it takes the timestamp, which internally is stored as an integer and divides by 86400.
'2015-12-08 20:58:58' / 86400 = 233231576.4566898000
It then uses the FLOOR operation which would make it 233231576 then multiplies by 86400 again (I assume that this is to ensure rounding to the day)
I end up with 20151208166400.
So that's the 8th December 2015 but I also have 166400 which I have no idea what it is?
So now the second part of the question is, how to convert this integer to 2015-12-08 %H:%i:%s or even a UTC timestamp for parsing via Javascript.
I mentioned the problem in the comment, but not a fix. The problem is that the proposed code is for a unix timestamp, not a datetime value.
This can be fixed by doing appropriate conversions
SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(MIN(timestamp)) / $period) * $period)
This gives you the flexibility of have arbitrary numbers of seconds for the groupings.
You're right that FLOOR(timestamp / 86400) * 86400 is a crude way of rounding a UNIX-style timestamp (seconds since 1970-01-01 00:00UTC) to midnight on the present day UTC.
If that's what you're trying to do, I suggest you try this kind of MySQL code:
SELECT DATE_FORMAT(DATE(`timestamp`), '%Y-%m-%d'),
...
GROUP BY DATE(`timestamp`)
This uses MySQL's built in date arithmetic to turn a timestamp into midnight.
But you should be careful of one thing. Those timestamps are all stored in UTC (f/k/a Greenwich Mean Time). When you do date arithmetic with them, or pull them out of the database to use them, they're automatically converted to local time according to your MySQL time zone settings.
It is rounding timestampt to period (e.g day).
DATE_FORMAT( DATE( FLOOR(MIN(timestamp)/"+period+")*"+period+" ) , '%Y-%m-%d %H:%i:%s' )
If period==day consider using only MySQL period rounding by DAY().
Convert a Date object to a string, according to universal time:
var d = new Date();
var n = d.toUTCString();
The result of n will be:
Mon, 28 Dec 2015 12:57:32 GMT

Should MySQL have its timezone set to UTC?

Follow up question of
https://serverfault.com/questions/191331/should-servers-have-their-timezone-set-to-gmt-utc
Should the MySQL timezone be set to UTC or should it be set to be the same timezone as the server or PHP is set? (If it is not UTC)
What are the pros and cons?
It seems that it does not matter what timezone is on the server as long as you have the time set right for the current timezone, know the timezone of the datetime columns that you store, and are aware of the issues with daylight savings time.
On the other hand if you have control of the timezones of the servers you work with then you can have everything set to UTC internally and never worry about timezones and DST, at least when it comes to storing internal time.
Here are some notes I collected of how to work with timezones as a form of cheatsheet for myself and others which might influence what timezone the person will choose for his/her server and how he/she will store date and time.
MySQL Timezone Cheatsheet
Notes:
Changing the timezone will not change the stored datetime or
timestamp, but it will select a different datetime from
timestamp columns
Warning! UTC has leap seconds, these look like '2012-06-30 23:59:60' and can
be added randomly, with 6 months prior notice, due to the slowing of
the earths rotation
GMT confuses seconds, which is why UTC was invented.
Warning! different regional timezones might produce the same datetime value due
to daylight savings time
The timestamp column only supports dates 1970-01-01 00:00:01 to 2038-01-19 03:14:07 UTC, due to a limitation.
Internally a MySQL timestamp column is stored as UTC but
when selecting a date MySQL will automatically convert it to the
current session timezone.
When storing a date in a timestamp, MySQL will assume that the date
is in the current session timezone and convert it to UTC for
storage.
MySQL can store partial dates in datetime columns, these look like
"2013-00-00 04:00:00"
MySQL stores "0000-00-00 00:00:00" if you set a datetime column as
NULL, unless you specifically set the column to allow null when you
create it.
Read this
To select a timestamp column in UTC format
no matter what timezone the current MySQL session is in:
SELECT
CONVERT_TZ(`timestamp_field`, ##session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
You can also set the sever or global or current session timezone to UTC and then select the timestamp like so:
SELECT `timestamp_field` FROM `table_name`
To select the current datetime in UTC:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), ##session.time_zone, '+00:00');
Example result: 2015-03-24 17:02:41
To select the current datetime in the session timezone
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
To select the timezone that was set when the server launched
SELECT ##system_time_zone;
Returns "MSK" or "+04:00" for Moscow time for example, there is (or was) a MySQL bug where if set to a numerical offset it would not adjust the Daylight savings time
To get the current timezone
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
It will return 02:00:00 if your timezone is +2:00.
To get the current UNIX timestamp (in seconds):
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
To get the timestamp column as a UNIX timestamp
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
To get a UTC datetime column as a UNIX timestamp
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', ##session.time_zone)) FROM `table_name`
Get a current timezone datetime from a positive UNIX timestamp integer
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
Get a UTC datetime from a UNIX timestamp
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), ##session.time_zone, '+00:00')
FROM `table_name`
Get a current timezone datetime from a negative UNIX timestamp integer
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
There are 3 places where the timezone might be set in MySQL:
Note: A timezone can be set in 2 formats:
an offset from UTC: '+00:00', '+10:00' or '-6:00'
as a named time zone: '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.
in the file "my.cnf"
default_time_zone='+00:00'
or
timezone='UTC'
##global.time_zone variable
To see what value they are set to
SELECT ##global.time_zone;
To set a value for it use either one:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET ##global.time_zone='+00:00';
##session.time_zone variable
SELECT ##session.time_zone;
To set it use either one:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET ##session.time_zone = "+00:00";
both "##global.time_zone variable" and "##session.time_zone variable" might return "SYSTEM" which means that they use the timezone set in "my.cnf".
For timezone names to work (even for default-time-zone) you must setup your timezone information tables need to be populated: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html
Note: you can not do this as it will return NULL:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Setup mysql timezone tables
For CONVERT_TZ to work, you need the timezone tables to be populated
SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;
If they are empty, then fill them up by running this command
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
if this command gives you the error "data too long for column 'abbreviation' at row 1", then it might be caused by a NULL character being appended at the end of the timezone abbreviation
the fix being to run this
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql
echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql
mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql
(make sure your servers dst rules are up to date zdump -v Europe/Moscow | grep 2011 https://chrisjean.com/updating-daylight-saving-time-on-linux/)
See the full DST (Daylight Saving Time) transition history for every timezone
SELECT
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND) AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC
CONVERT_TZ also applies any necessary DST changes based on the rules in the above tables and the date that you use.
Note:
According to the docs, the value you set for time_zone does not change, if you set it as "+01:00" for example, then the time_zone will be set as an offset from UTC, which does not follow DST, so it will stay the same all year round.
Only the named timezones will change time during daylight savings time.
Abbreviations like CET will always be a winter time and CEST will be summer time while +01:00 will always be UTC time + 1 hour and both won't change with DST.
The system timezone will be the timezone of the host machine where mysql is installed (unless mysql fails to determine it)
You can read more about working with DST here
When not to use UTC by the legendary Jon Skeet: https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/
(For example a scheduled event in the future that represents a time, not an instant in time)
related questions:
How do I set the time zone of MySQL?
MySql - SELECT TimeStamp Column in UTC format
How to get Unix timestamp in MySQL from UTC time?
Converting Server MySQL TimeStamp To UTC
https://dba.stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
How do I get the current time zone of MySQL?
MySQL datetime fields and daylight savings time -- how do I reference the "extra" hour?
Converting negative values from FROM_UNIXTIME
Sources:
https://bugs.mysql.com/bug.php?id=68861
http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html
http://dev.mysql.com/doc/refman/5.1/en/datetime.html
http://en.wikipedia.org/wiki/Coordinated_Universal_Time
http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
https://web.ivy.net/~carton/rant/MySQL-timezones.txt
PHP and MySQL have their own default timezone configurations. You should synchronize time between your data base and web application, otherwise you could run some issues.
Read this tutorial: How To Synchronize Your PHP and MySQL Timezones
This is a working example:
jdbc:mysql://localhost:3306/database?useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Europe/Moscow
The pros and cons are pretty much identical.It depends on whether you want this or not.
Be careful, if MySQL timezone differs from your system time (for instance PHP), comparing the time or printing to the user will involve some tinkering.
How about making your app agnostic of the server's timezone?
Owing to any of these possible scenarios:
You might not have control over the web/database server's timezone settings
You might mess up and set the settings incorrectly
There are so many settings as described in the other answers, and so many things to keep track of, that you might miss something
An update on the server, or a software reset, or another admin, might unknowing reset the servers' timezone to the default - thus breaking your application
All of the above scenarios give rise to breaking of your application's time calculations. Thus it appears that the better approach is to make your application work independent of the server's timezone.
The idea is simply to always create dates in UTC before storing them into the database, and always re-create them from the stored values in UTC as well. This way, the time calculations won't ever be incorrect, because they're always in UTC. This can be achieved by explicity stating the DateTimeZone parameter when creating a PHP DateTime object.
On the other hand, the client side functionality can be configured to convert all dates/times received from the server to the client's timezone. Libraries like moment.js make this super easy to do.
For example, when storing a date in the database, instead of using the NOW() function of MySQL, create the timestamp string in UTC as follows:
// Storing dates
$date = new DateTime('now', new DateTimeZone('UTC'));
$sql = 'insert into table_name (date_column) values ("' . $date . '")';
// Retreiving dates
$sql = 'select date_column from table_name where condition';
$dateInUTC = new DateTime($date_string_from_db, new DateTimeZone('UTC'));
You can set the default timezone in PHP for all dates created, thus eliminating the need to initialize the DateTimeZone class every time you want to create a date.
Check Timezone
SELECT ##system_time_zone as System_tz ,##global.time_zone as MYSQL_timeZone, NOW() as timenow_bymysql;
SET GLOBAL time_zone = '+05:30';
OR
change system time zone then restart MariaDB/MYSQL
and check again timezone

UNIX timestamp on MySQL and MSSQL Server

How come there is a difference on timestamps in mysql and MS SQL Server
MySQL:
select now() result: 2013-07-16 08:49:26.0
SQL Server:
select getdate() result: 2013-07-16 08:48:16.47
and when I try to get unix_timestamp
MySQL:
SELECT UNIX_TIMESTAMP('2013-07-01') result: 1372629600
SQL Server:
SELECT DATEDIFF(SECOND,'1970-01-01', '2013-07-01') result 1372636800
problem: there is a difference of 7200 seconds (2h)
Is this a Time Zone problem, server time on both servers are the same as seen on now() and getdate()?
This is quite a long solution but it seems to work. It accounts for the offset in time zones.
SELECT DATEDIFF(SECOND, DATEADD(SECOND, DATEDIFF(SECOND, GETUTCDATE(), GETDATE()), '1970-01-01'), '2013-07-01')
On SQL Server use
select datediff(ss, '1970-01-01', SYSDATETIMEOFFSET() at time zone 'UTC')
Here,
SYSDATETIMEOFFSET() returns the local system time with the local time zone offset enabling the conversion to UTC. Replace it with your own datetimeoffset field if you want something other than the current time.
You can try this link for understanding timestamp in Mysql
http://www.mysqltutorial.org/mysql-timestamp.aspx
for tsql timestamp you can check out these links
http://www.informit.com/library/content.aspx?b=STY_Sql_Server_7&seqNum=97
http://technet.microsoft.com/en-us/library/ms188751(v=sql.110).aspx
Sorry for the late answer, but this will only work for dates NOW. If you have to analyze dates in the past and you have e.g. different time zones (summer/wintertime) this will not work properly.

Convert Unix timestamp into human readable date using MySQL

Is there a MySQL function which can be used to convert a Unix timestamp into a human readable date? I have one field where I save Unix times and now I want to add another field for human readable dates.
Use FROM_UNIXTIME():
SELECT
FROM_UNIXTIME(timestamp)
FROM
your_table;
See also: MySQL documentation on FROM_UNIXTIME().
What's missing from the other answers (as of this writing) and not directly obvious is that from_unixtime can take a second parameter to specify the format like so:
SELECT
from_unixtime(timestamp, '%Y %D %M %H:%i:%s')
FROM
your_table
I think what you're looking for is FROM_UNIXTIME()
Need a unix timestamp in a specific timezone?
Here's a one liner if you have quick access to the mysql cli:
mysql> select convert_tz(from_unixtime(1467095851), 'UTC', 'MST') as 'local time';
+---------------------+
| local time |
+---------------------+
| 2016-06-27 23:37:31 |
+---------------------+
Replace 'MST' with your desired timezone. I live in Arizona 🌵 thus the conversion from UTC to MST.
Why bother saving the field as readable? Just us AS
SELECT theTimeStamp, FROM_UNIXTIME(theTimeStamp) AS readableDate
FROM theTable
WHERE theTable.theField = theValue;
EDIT: Sorry, we store everything in milliseconds not seconds. Fixed it.
You can use the DATE_FORMAT function. Here's a page with examples, and the patterns you can use to select different date components.
Easy and simple way:
select from_unixtime(column_name, '%Y-%m-%d') from table_name
Since I found this question not being aware, that mysql always stores time in timestamp fields in UTC but will display (e.g. phpmyadmin) in local time zone I would like to add my findings.
I have an automatically updated last_modified field, defined as:
`last_modified` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Looking at it with phpmyadmin, it looks like it is in local time, internally it is UTC
SET time_zone = '+04:00'; // or '+00:00' to display dates in UTC or 'UTC' if time zones are installed.
SELECT last_modified, UNIX_TIMESTAMP(last_modified), from_unixtime(UNIX_TIMESTAMP(last_modified), '%Y-%c-%d %H:%i:%s'), CONVERT_TZ(last_modified,##session.time_zone,'+00:00') as UTC FROM `table_name`
In any constellation, UNIX_TIMESTAMP and 'as UTC' are always displayed in UTC time.
Run this twice, first without setting the time_zone.
If you would like to convert time AND display the data in a specific format you can use this string.
date_format(convert_tz(from_unixtime(TIMESTAMP), 'UTC', 'DESIRED TZ'), '%m/%d/%y')
where you add convert_tz to a date_format string. the %m/%d/%y being month/day/year.
you can find all the specific formats here https://www.w3schools.com/sql/func_mysql_date_format.asp