Error: Update Varchar values to Datetime in MySQL - mysql

DB DETAIL Table name(KK)-
id name date(varchar(50))
1 Ayush 2020-04-19T18:56:09.774Z
I am using this query to convert -
update KK set date=DATE_FORMAT(STR_TO_DATE( KK.date, '%Y-%m-%dT%H:%i:%s' ), '%Y-%m-%d %T') where id=1;
Getting this error
Error Code: 1292. Truncated incorrect datetime value: '2020-04-19T18:56:09.774Z'

Your current date string has .774Z following the seconds, but your STR_TO_DATE() format string doesn't account for it. So it's warning you that there are extra characters at the end of the string that weren't parsed.
If you use '%Y-%m-%dT%H:%i:%s.%fZ' the warning stops.

The times have two parts your format is missing: milliseconds, the .774 part, and the "zulu" time zone Z.
select STR_TO_DATE('2020-04-19T18:56:09.774Z', '%Y-%m-%dT%H:%i:%s.%fZ');
However, since you're truncating them anyway, I'd use the less restrictive format and just ignore the warning.
Since the string is already in ISO 8601 format, you can skip the str_to_date.
mysql> select DATE_FORMAT('2020-04-19T18:56:09.774Z', '%Y-%m-%d %T');
+--------------------------------------------------------+
| DATE_FORMAT('2020-04-19T18:56:09.774Z', '%Y-%m-%d %T') |
+--------------------------------------------------------+
| 2020-04-19 18:56:09 |
+--------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
The MySQL warning is because it doesn't seem to understand that Z is a valid time zone designator.
Note that this will account for a time zone. This may or may not be what you want.
-- date_format will display in the current time zone.
-- I'm in -07:00, so a +00:00 (UTC) date is displayed -7 hours.
mysql> select DATE_FORMAT('2020-04-19T18:56:09.777+00:00', '%Y-%m-%d %T');
+-------------------------------------------------------------+
| DATE_FORMAT('2020-04-19T18:56:09.777+00:00', '%Y-%m-%d %T') |
+-------------------------------------------------------------+
| 2020-04-19 11:56:09 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
And, finally, consider altering that column to be a datetime type. Then everything is stored in UTC and these conversion problems go away.

Related

Convert datetime column to 24 hour format

I have a column called schedule_time (datetime) format. I want to convert the time to 24 hour time.
2016-03-08 03:00:00 to 2016-03-08 15:00:00
Please note that DATETIME values are always stored in 24h format (http://dev.mysql.com/doc/refman/5.7/en/datetime.html). There is no AM/PM.
When you want to display the values, there is however the DATE_FORMAT
function, which will format the value according to your needs, including AM/PM:
select DATE_FORMAT(schedule_time, '%Y-%m-%d %h:%i:%s %p') from t1;
This will give 2016-03-08 03:00:00 AM and 2016-03-08 03:00:00 PM. But the values in the DB are still the same, in 24h format.
If adding 12 hours would solve your issue, the you can do it like this:
start transaction;
update t1 set schedule_time = date_add(schedule_time, interval 12 hour);
select * from t1; -- verify!!!
rollback;
-- or commit;
I put this in a transaction so you can first verify your results. If they are wrong, simply rollback the transaction (provided you use InnoDB tables). If you don't have transactions (or feel uncomfortable with them), you can undo the change with date_sub instead of date_add.
But be aware: This doesn't change from 12h to 24h format, it simply adds 12 hours to all your schedule_time values.
Use MySQL's DATE_FORMAT function.
The format string will be '%Y-%m-%d %T'.
Selecting the current date with 24-hour time:
mysql> SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %T') AS now
+---------------------+
| now |
+---------------------+
| 2016-03-08 20:47:04 |
+---------------------+
1 row in set (0.00 sec)
Selecting a date with 24-hour time from a table:
mysql> SELECT DATE_FORMAT(`created_at`, '%Y-%m-%d %T') AS created_at FROM test.comments;
+---------------------+
| created_at |
+---------------------+
| 2016-02-25 16:32:12 |
+---------------------+
1 row in set (0.00 sec)

Mysql Timestamp difference results

I have a table with a TIMESTAMP field (lastHonored).
I ran this query:
SELECT NOW(), lastHonored,
TIMESTAMPDIFF(SECOND, lastHonored, NOW()), NOW()-lastHonored
FROM db.table
I get the result:
NOW() | lastHonored | DIFF | SUBTRACT
2014-10-27 14:07:22 | 2014-10-26 19:49:51 | 65851 | 945771
Where DIFF is the result of the TIMESTAMPDIFF function, and SUBTRACT is the result of the NOW()-lastHonored expresssion.
DIFF looks right, but can anyone tell me what NOW()-lastHonored calculates? It is not the right order of magnitude, and I'm stumped.
One would think that NOW() returns a datetime or similar type. But no. For some historical reason, NOW() returns either a number or a string. To quote the documentation:
Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS'
or YYYYMMDDHHMMSS format, depending on whether the function is used in
a string or numeric context. The value is expressed in the current
time zone.
That means that NOW() gets converted to a value based on its context. The - suggests a numeric context, so NOW() is a number whose digits are YYYYMMDDHHMMSS. My guess is that lastHonored gets similarly converted, so the result is the difference between two numbers.
You can see why by running:
SELECT CAST(NOW() AS UNSIGNED), CAST('2014-10-26 19:49:51' AS UNSIGNED);
By doing simple subtraction, MySQL is turning both values into numbers. NOW() the DATETIME becomes 20141027141923, but 2014-10-26 19:49:51 the STRING becomes 2014.
If you first cast the date to a DATETIME it gives you results more along the lines of what you expect:
SELECT CAST(NOW() AS UNSIGNED), CAST(CAST('2014-10-26 19:49:51' AS DATETIME) AS UNSIGNED);
You can't subtract dates like you are with NOW()-lastHonored. Dates/datetimes are not directly "subtractable":
MariaDB [test]> select '2014-10-27 08:18:00' - '2014-10-27 08:17:00';
+-----------------------------------------------+
| '2014-10-27 08:18:00' - '2014-10-27 08:17:00' |
+-----------------------------------------------+
| 0 |
+-----------------------------------------------+
1 row in set, 2 warnings (0.00 sec)
MariaDB [test]> show warnings;
+---------+------+---------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '2014-10-27 08:18:00' |
| Warning | 1292 | Truncated incorrect DOUBLE value: '2014-10-27 08:17:00' |
+---------+------+---------------------------------------------------------+
2 rows in set (0.00 sec)
Note the warnings. You'll get results, but they almost always be totally useless/incorrect results, because MySQL is casting the date values as doubles.
They do different things, substraction does not take into account that you are dealing with times.
If you do:
SELECT NOW(), lastHonored,
TIMESTAMPDIFF(SECOND, lastHonored, NOW()) THE_DIFF, NOW()-lastHonored THE_SUBSTRACTION,
NOW()+0 NOW_NUMBER_REPRESNTATION,
lastHonored+0 lastHonored_NUMBER_REPRESENTATION
FROM db.table
You will see the numeric difference is represented with the substraction and the time differente with TIMESTAMPDIFF.

MySQL TIMEDIFF(DATE, DATETIME)

I have two columns in MySQL database.
One is in DATE format like 2014-01-26, another one is in DATETIME format: 2014-01-25 17:19:07.
I need to apply TIMEDIFF(2014-01-26, 2014-01-25 17:19:07) function, but it requires both variables are in DATETIME format. How can I convert 2014-01-26 to 2014-01-26 00:00:00?
You can always cast a Date to a datetime
select timediff(cast(<yourDateColumn> as Datetime), <yourDatetimeColumn>)
But I'm not even really sure that you need to cast (depending on your mysql version), I may misunderstand the doc, but we can read
Prior to MySQL 5.1.18, when DATE values are compared with DATETIME
values, the time portion of the DATETIME value is ignored, or the
comparison could be performed as a string compare. Starting from MySQL
5.1.18, a DATE value is coerced to the DATETIME type by adding the time portion as '00:00:00'. To mimic the old behavior, use the CAST()
function to cause the comparison operands to be treated as previously.
For example:
You can use date_format()
mysql> select
TIMEDIFF(date_format('2014-01-26','%Y-%m-%d %H:%i:%s'), '2014-01-25 17:19:07')
as diff;
+----------+
| diff |
+----------+
| 06:40:53 |
+----------+
1 row in set (0.00 sec)
mysql> select date_format('2014-01-26','%Y-%m-%d %H:%i:%s') as date;
+---------------------+
| date |
+---------------------+
| 2014-01-26 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

MySql unix_time() function with only date argument

Ok, so the following works fine
mysql> SELECT UNIX_TIMESTAMP('2007-11-30 10:30:19');
But if I give only a date argument, like in:
mysql> SELECT UNIX_TIMESTAMP('2007-11-30');
Then somehow I am getting the timestamp equivalent to 2007-11-30 18:30 GMT. Can I somehow reset it to give timestamp for the beginning of that particular day? Like UNIX_TIMESTAMP('2007-11-30'); should give the timestamp equivalent of UNIX_TIMESTAMP('2007-11-30 00:00:00'); I need to filter out some records from a table based an event that happend after a certain date.
Thanks
[EDIT]: I don't know how but this seems to be working as expected now. Screenshots: 2007-11:30 00:00:00 2007-11:30 18:30:00 2007-11:30
I have checked it But i am getting same timestamp for '2007-11-30 00:00:00' and '2007-11-30'
mysql> SELECT UNIX_TIMESTAMP('2007-11-30 00:00:00');
+---------------------------------------+
| UNIX_TIMESTAMP('2007-11-30 00:00:00') |
+---------------------------------------+
| 1196361000 |
+---------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT UNIX_TIMESTAMP('2007-11-30');
+------------------------------+
| UNIX_TIMESTAMP('2007-11-30') |
+------------------------------+
| 1196361000 |
+------------------------------+
Can you run these queries on your machine and check timestamp values.
I also checked, for me as well it is giving for 00:00:00. On further investigation, I came across this Here:
The server interprets date as a value in the current time zone and
converts it to an internal value in UTC. Clients can set their time
zone as described in Section 10.6, “MySQL Server Time Zone Support”.
On further searching, it became apparent that there is a variable system_time_zone, that is set when server starts using server machine's timezone. See here also
For each client connecting, they can set their own timezone as
mysql> SET time_zone = timezone;
So finally, you need to check your system_time_zone, set it to proper value.
I hope it will work well then....
Found a way to make sure, that the UNIX_TIMESTAMP function returns the correct timestamp irrespective of anything interfering with the timezone etc
>> SELECT UNIX_TIMESTAMP(CONCAT(t.DATE,' 00:00:00')) FROM db.table_name t
That is, to append the 00:00:00 manually in the query string.

how to change default date format when creating table in MYSQL

how to change default date format when creating table in MYSQL
You can't change the default format for a date during the table definition stage. (It must always obey the DATETIME, DATE or TIMESTAMP formats.) As the manual puts it:
Although MySQL tries to interpret
values in several formats, dates
always must be given in year-month-day
order (for example, '98-09-04'),
rather than in the month-day-year or
day-month-year orders commonly used
elsewhere (for example, '09-04-98',
'04-09-98').
See the date and time reference docs for more info.
As such, you'll have to use the DATE_FORMAT() function at the point of output to achieve this goal.
You may want to use the STR_TO_DATE() and DATE_FORMAT() functions to communicate with MySQL using different date formats.
Example using STR_TO_DATE():
SELECT STR_TO_DATE('15-Dec-09 1:00:00 PM', '%d-%b-%y %h:%i:%S %p') AS date;
+---------------------+
| date |
+---------------------+
| 2009-12-15 13:00:00 |
+---------------------+
1 row in set (0.07 sec)
Example using DATE_FORMAT():
SELECT DATE_FORMAT('2009-12-15 13:00:00', '%d-%b-%y %h:%i:%S %p') AS date;
+-----------------------+
| date |
+-----------------------+
| 15-Dec-09 01:00:00 PM |
+-----------------------+
1 row in set (0.00 sec)