mysql CONVERT_TZ inconsistent behavior - mysql

The following behavior puzzles me. My mysql server is installed on a PC with EEST timezone.
I want to convert a datetime in mysql to UTC date.
When executing
select CONVERT_TZ('1970-01-01 02:00:01', 'SYSTEM', '+00:00')
the reponse is:
'1970-01-01 00:00:01'
Similarly, when executing
select CONVERT_TZ('1970-01-01 04:00:00', 'SYSTEM', '+00:00')
the response is:'1970-01-01 02:00:00'
However, when I basically want the 0 unix time, by executing:
select CONVERT_TZ('1970-01-01 02:00:00', 'SYSTEM', '+00:00')
The reponse is again: '1970-01-01 02:00:00'
Why is that? Am I doing something wrong? How can I get the correct value which is '1970-01-01 00:00:00'?

I think the issue here is that an adjustment made in CONVERT_TZ which would result in a timestamp on or before the start of the UNIX epoch will be ignored, and the original input timestamp will be returned. Consider the following three queries:
SELECT CONVERT_TZ('1970-01-01 01:00:01', 'SYSTEM', '+00:00');
-- '1970-01-01 00:00:01'
SELECT CONVERT_TZ('1970-01-01 01:00:00', 'SYSTEM', '+00:00');
-- '1970-01-01 01:00:00'
SELECT CONVERT_TZ('1970-01-01 00:30:00', 'SYSTEM', '+00:00');
-- '1970-01-01 00:30:00'
Only the first query adjusts the timestamp; the second two just return the input.
From the excellent comments given by #Thomas above, I pulled the following from the MySQL documentation for CONVERT_TZ:
If the value falls out of the supported range of the TIMESTAMP type when converted from from_tz to UTC, no conversion occurs.

Related

MySQL - How to select rows where datetime field is not equal to 0000-00-00 00:00:00?

Here is my table "tb_posts":
I want to select only those rows where datetime field i.e. post_date_published is not equal to 0000-00-00 00:00:00. I am using following query but it doesn't work:
SELECT * FROM `tb_posts` WHERE `post_date_published` IS NOT NULL
I am getting the same output as shown in the above picture.
Why IS NOT NULL is not working?
As per the MYSQL documentation it saves invalid dates as '0000-00-00 00:00:00'. It will not be considered as NULL.
Try comparing with the date '0000-00-00 00:00:00':
SELECT * FROM tb_posts where post_date_published != '0000-00-00 00:00:00'
A method I use with this sort of thing is
SELECT `columns` FROM `tb_posts` WHERE UNIX_TIMESTAMP(`post_date_published`) > 0
From the MySQL Documentation:
The valid range of argument values is the same as for the TIMESTAMP
data type: '1970-01-01 00:00:01.000000' UTC to '2038-01-19
03:14:07.999999' UTC. If you pass an out-of-range date to
UNIX_TIMESTAMP(), it returns 0.
The UNIX_TIMESTAMP function forces the result to be an integer so it's much easier to work with in these quick comparisons. It is also vital for working with MySQL 5.7 where "empty" (ie zero value) date/time columns are not allowed.
(I had a lot of grief trying to convert various date columns to NULL because MySQL 5.7+ didn't recognise 0000-00-00 00:00:00 as a valid comparison -- so I converted it to a unix timestamp so as to compare the timestamp rather than the actual [invalid] date.)

How to convert date into timestamp in SQL query?

I'm trying to migrate data from old_table to new_table, but in old table the date datatype is datetime and in new table the date datatype is int and is accepting timestamp value.
So how to convert the old date in sql query so that it get inserted in new table as timestamp?
INSERT INTO `new_table` (`id`, `user_id`, `doctor_id`, `message_id`, `type`, `is_message`, `is_note`, `doctor_initials`, `call_status`, `message`, `date_created`, `date_updated`, `day`)
SELECT id, usid, drid, message_id, type, is_message, is_note, doctor, kall, message, datein, 123, ziua
FROM `old_table`;
I want a function which convert old date to value to timestamp e.g in the above query CONVERT_INTO_TIMESTAMP(datein)
Any help will be highly appreciated.
New Table date_created field accepts values in unix timestamp such as : 1540642765
Thanks
The function you are looking for is UNIX_TIMESTAMP(), e.g.
select UNIX_TIMESTAMP('1970-01-01 00:00:00');
gives 0 in the UTC timezone.
Try UNIX_TIMESTAMP() function:
INSERT INTO `new_table`
(`id`,
`user_id`,
`doctor_id`,
`message_id`,
`type`,
`is_message`,
`is_note`,
`doctor_initials`,
`call_status`,
`message`,
`date_created`,
`date_updated`,
`day`)
SELECT id,
usid,
drid,
message_id,
type,
is_message,
is_note,
doctor,
kall,
message,
Unix_timestamp(datein),
'123',
ziua
FROM `old_table`;
From Docs:
If called with no argument, returns a Unix timestamp (seconds since
'1970-01-01 00:00:00' UTC) as an unsigned integer. If UNIX_TIMESTAMP()
is called with a date argument, it returns the value of the argument
as seconds since '1970-01-01 00:00:00' UTC. The date argument may be a
DATE, DATETIME, or TIMESTAMP string, or a number in YYMMDD,
YYMMDDHHMMSS, YYYYMMDD, or YYYYMMDDHHMMSS format. The server
interprets date as a value in the current time zone and converts it to
an internal value in UTC.
SELECT date_part('epoch', CURRENT_TIMESTAMP)::int;
since this question is also tagged for SQL
people who came here for timestamp solution in SQL/MSSQL Query. can try below
SELECT CAST(DueDate AS TIMESTAMP) "NewDueDate"
where DueDate is column with having date like - YYYY-MM-DD HH:ii:ss .
if your column is in type varchar then still above syntax will work fine.

MySQL incorrect timestamp value

I'm trying to insert datetime value '1970-01-01 00:00:01' in timestamp column but MySQL returned an error "Incorrect datetime value: '1970-01-01 00:00:01' for column 'timestamp'"
CREATE TABLE TST_TABLE
(
tst_column timestamp NULL
)
INSERT INTO TST_TABLE(tst_column) VALUES('1970-01-01 00:00:01');
I'm confused because MySQL documentation claims that lowest valid value for timestamp is '1970-01-01 00:00:01'. What's wrong and what is real lowest timestamp value?
Thanks.
This is a timezone issue. Set the timezone to UTC before the insert, for example :
SET time_zone='+00:00';
INSERT INTO TST_TABLE(tst_column) VALUES('1970-01-01 00:00:01');
An other option is to convert you timestamp to the UTC timezone using CONVERT_TZ. For exemple, if your timezone is Europe/Paris :
INSERT INTO TST_TABLE(tst_column) VALUES(CONVERT_TZ('1970-01-01 00:00:01', 'Europe/Paris', 'UTC'));

I am coverting unix timestamp to Datetime format in mysql .But it is showing NULL as an output

select FROM_UNIXTIME(32154654321);
Output:Null
Expected Result: Tuesday, December 9, 2988 1:55:21 PM GMT+05:30
This is why: https://dev.mysql.com/doc/refman/5.5/en/datetime.html
The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
This is the Year-2038 problem. The maximum value of the TIMESTAMP datatype is 2038-01-19 03:14:07, so you can't get the expected result.
MySQL 5.5: The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.
source: https://dev.mysql.com/doc/refman/5.5/en/datetime.html
MySQL 5.6+: [...] and the range for TIMESTAMP values is '1970-01-01 00:00:01.000000' to '2038-01-19 03:14:07.999999'.
source: https://dev.mysql.com/doc/refman/5.7/en/datetime.html
You can find a very good answer on stackoverflow with some more details about this problem.
You can use PHP instead of MySQL to convert the timestamp (not stored in a TIMESTAMP column) to a readable datetime, with the following code:
$timestamp = 32154654321;
$format = 'Y-m-d H:i:s';
$date = new DateTime();
$date->setTimestamp($timestamp);
echo $date->format($format);
demo: http://ideone.com/DsYUOQ
You cannot input like 32154654321
Timestamps in mysql have a maximum value of 2147483647, equivalent
to 2038-01-19 05:14:07. This is due to the underlying 32-bit
limitation. Using the function on a timestamp beyond this will result
in NULL being returned. Use DATETIME as a storage type if you require
dates beyond this.

How to convert DateTime to a number in MySQL?

How can I get the total number of seconds since '1970-01-01 00:00:01' from a DateTime instance in MySQL?
You are looking for UNIX_TIMESTAMP().
See: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_unix-timestamp
If UNIX_TIMESTAMP() is called with a date argument, it returns the value of the argument as seconds since '1970-01-01 00:00:00' UTC.
Use UNIX_TIMESTAMP( dateField )
SELECT DATE_FORMAT(`value`, '%Y%m%d') AS `date_ymd` FROM `table_name`;
UNIX_TIMESTAMP(datetime) force a localization of the datetime, which unlike the timestamp, is stored "as is".
You need actually any of the following, for discarding the UTC correction:
UNIX_TIMESTAMP(CONVERT_TZ(datetime, '+00:00', ##session.time_zone))
or:
TIMESTAMPDIFF(SECOND,'1970-01-01 00:00:00',datetime)
Refs: 1, 2, 3, 4