mysql time_format function qustion - mysql

I insert and update mysql time_format function to express string value in time,
Why do some numbers get
"truncated incorrect time value"
errors?
For example, '55' is not a problem with query, but when '188' is entered, the above error message appears.
The type is VARCHAR (50).
my query :
INSERT INTO TABLE_HOME (DURATION)
VALUES (TIME_FORMAT (# {DURATION, jdbcType = VARCHAR}, '% H:% i:% s'))
UPDATE TABLE_HOME SET DURATION = TIME_FORMAT (# {DURATION, jdbcType = VARCHAR}, '% H:% i:% s')

Time_Format not all integers are valid..
188 is not a valid time anymore
Even where you placed it:
"%H= Hour => 188?
%i=Minute => 188?
%s"=Second => 188?
Do you think 188 is a valid time of an Hour, Minute, Second?

TIME_FORMAT() expects a time. If you feed it with anything else, you first get a cast. In this case:
mysql> SELECT CAST(55 AS TIME), CAST(188 AS TIME);
+------------------+-------------------+
| CAST(55 AS TIME) | CAST(188 AS TIME) |
+------------------+-------------------+
| 00:00:55 | NULL |
+------------------+-------------------+
1 row in set, 1 warning (0.00 sec)
The rules are:
MySQL recognizes TIME values in these formats:
As a string in 'D HH:MM:SS' format. You can also use one of the following “relaxed” syntaxes: 'HH:MM:SS', 'HH:MM', 'D HH:MM', 'D HH',
or 'SS'. Here D represents days and can have a value from 0 to 34.
As a string with no delimiters in 'HHMMSS' format, provided that it makes sense as a time. For example, '101112' is understood as
'10:11:12', but '109712' is illegal (it has a nonsensical minute part)
and becomes '00:00:00'.
As a number in HHMMSS format, provided that it makes sense as a time. For example, 101112 is understood as '10:11:12'. The following
alternative formats are also understood: SS, MMSS, or HHMMSS.
In this case, #3 applies:
55 is rendered as SS so it's valid.
188 is not a supported format so it produces NULL.
Date and time handling is already hard enough. I suggest to:
Be explicit to avoid ambiguity (something like 23:30:45 is crystal clear, 188 is open to interpretations).
Not use VARCHAR columns to store dates and times.

Related

Insert a 4-digit as Time in MySql

My data contains hour & minute of time and I want to load this data into MySql database.
Sample Data: 305 -- This means Hours=03 & Minutes=05
But when I upload the data into MySql column of type TIME, it is stored as 00:03:05 (HH:MM:SS).
Whereas, I want it to be stored as 03:05:00.
I can make changes to my data using Python & then load into MySql. However, I was wondering if there is a way to do it using MySql itself.
It is not up to MySQL to guess what you mean by "305". It's up to you to convert/format yor data to "03:05:00", then MySQL will undertand it properly.
insert into try (elasp) values ("03:05:00")
See MySQL documentation: https://dev.mysql.com/doc/refman/8.0/en/time.html
While converting to TIME datatype the numeric value is assumed to have HHMMSS format.
MySQL 8.0 Reference Manual / ... / The TIME Type:
Be careful about assigning abbreviated values to a TIME column. MySQL interprets abbreviated TIME values with colons as time of the day. That is, '11:12' means '11:12:00', not '00:11:12'. MySQL interprets abbreviated values without colons using the assumption that the two rightmost digits represent seconds (that is, as elapsed time rather than as time of day). For example, you might think of '1112' and 1112 as meaning '11:12:00' (12 minutes after 11 o'clock), but MySQL interprets them as '00:11:12' (11 minutes, 12 seconds). Similarly, '12' and 12 are interpreted as '00:00:12'.
If you want to use HHMM format during convertion then simply multiply the value by 100.
CREATE TABLE test (int_source INT, time_destination TIME);
INSERT INTO test (int_source) VALUES ('305');
SELECT * FROM test;
UPDATE test SET time_destination = int_source * 100;
SELECT * FROM test;
✓
✓
int_source | time_destination
---------: | :---------------
305 | null
✓
int_source | time_destination
---------: | :---------------
305 | 03:05:00
db<>fiddle here
Or, if the value to be converted to TIME datatype has some string type you may concatenate '00' to it:
SET time_destination = CONCAT(int_source, '00')

MySQL TIME type having hours>23

How I can force MySQL display TIME columns data from 3.07:10:10 to 79:10:10?
So the query SELECT item FROM table_ should return the TIME in the 79:10:10 format.
edit: TIME stores hours, from '-838:59:59' to '838:59:59'.
I tried SELECT TIME_FORMAT('3.07:10:10', '%H:%i:%s') and unexpectedly it returns 00:00:03
(I blamed the OP because I thought TIME columns can only store up to 24 hrs. That's not true: They can store up to ±838 hours. Sorry & thanks for that.)
To insert/use days in TIME columns, use the following syntax:
mysql> SELECT TIME('3 07:10:10');
+--------------------+
| TIME('3 07:10:10') |
+--------------------+
| 79:10:10 |
+--------------------+
1 row in set (0.00 sec)
That is: replace the dot in 3.07:10:10 with a blank.
From the docs:
MySQL recognizes TIME values in these formats:
As a string in 'D HH:MM:SS' format. You can also use one of the following “relaxed” syntaxes: 'HH:MM:SS', 'HH:MM', 'D HH:MM', 'D HH',
or 'SS'. Here D represents days and can have a value from 0 to 34.
...
If you insert '3 07:10:10' into a TIME column, it will automatically give 79:10:10 on select.

Getting date and time of datetime (bug in MySQL?)

Running the following statement, MySQL seems to mix things up:
select now(), if(false, date(now()), time(now()));
| 2013-07-24 10:06:21 | 2010-06-21 00:00:00 |
If replacing the second argument of the if with a literal string, the statement behaves correctly:
select now(), if(false, 'Banana', time(now()));
| 2013-07-24 10:06:21 | 10:06:21 |
Is this a bug or some really strange quirk?
The return type of IF has to be a datatype that includes the types of both arguments. So if one of the arguments is a DATE and the other is a TIME, the type of IF will be DATETIME.
This doesn't seem necessary in the trivial example query, but consider something like:
SELECT IF(col1, date(col2), time(col2)) AS dt
FROM Table
All the rows of the result have to have the same datatype in the dt column, even though the specific data will depend on what's in that row.
If you want just the date or time, convert it to a string.

Mysql date function not working for less than

I need to get all records those equal and less than 2012-12-28 i used bellow query for this,
booking_time is DATETIME field, and there are records less than 2012-12-28 but it returns zero rows.
does anyone has idea ?
SELECT * FROM ctx_bookings WHERE DATE(booking_time)<=2012-12-28 ORDER BY id ASC
Table filed
+---------------------+
| booking_time |
+---------------------+
| 2012-12-20 03:10:09 |
| 2012-12-25 02:10:04 |
+---------------------+
Please anybody know why is this happening ?
wrap the value with single quote and surely it will work
SELECT *
FROM ctx_bookings
WHERE DATE(booking_time) <= '2012-12-28'
ORDER BY id ASC
SQLFiddle Demo
As documented under Date and Time Literals:
MySQL recognizes DATE values in these formats:
As a string in either 'YYYY-MM-DD' or 'YY-MM-DD' format. A “relaxed” syntax is permitted: Any punctuation character may be used as the delimiter between date parts. For example, '2012-12-31', '2012/12/31', '2012^12^31', and '2012#12#31' are equivalent.
As a string with no delimiters in either 'YYYYMMDD' or 'YYMMDD' format, provided that the string makes sense as a date. For example, '20070523' and '070523' are interpreted as '2007-05-23', but '071332' is illegal (it has nonsensical month and day parts) and becomes '0000-00-00'.
As a number in either YYYYMMDD or YYMMDD format, provided that the number makes sense as a date. For example, 19830905 and 830905 are interpreted as '1983-09-05'.
As #Barmar commented, your literal expression 2012-12-28 is evaluated as the arithmetic (2012 - 12) - 28, which equals 1,972.
Per #JW.'s answer, you can quote that expression to obtain a valid date literal (of the first form, above). Alternatively:
whilst still quoting the literal, you could use any other punctuation character (or even no character) as the delimiter between date parts:
WHERE DATE(booking_time) <= '2012_12_28'
WHERE DATE(booking_time) <= '20121228'
you could remove the delimiters and leave your literal unquoted:
WHERE DATE(booking_time) <= 20121228
Note also that using a filter criterion like this, which uses a function (in this case, the DATE() function) over a column, requires a full table scan in order to evaluate that function—it therefore will not benefit from any indexes. A more sargable alternative would be to filter more explicitly over the range of column values (i.e. times) that satisfy your criteria:
WHERE booking_time < '2012-12-28' + INTERVAL 1 DAY
This is equivalent because any time that falls strictly prior to the following day will necessarily have occurred on or before the day of interest. It is sargable because the column is compared to a constant expression (the result of the + operation being deterministic), and therefore an index over booking_time can be traversed to immediately find all matching records.
SELECT * FROM ctx_bookings WHERE DATE(booking_time)<='2012-12-28' ORDER BY id ASC
try this mate

What is the behavior for the minus operator between two datetimes in MySQL?

The difference between to datetimes is the number of seconds between them. This seems to work only if the datetimes occur in the same hour.
Why is this?
mysql> update events set created_at = "2011-04-13 15:59:59", fulfilled_at ="2011-04-13 16:00:00" where id = 1;
mysql> select fulfilled_at - created_at, timediff(fulfilled_at, created_at) from events where id = 1;
+---------------------------+------------------------------------+
| fulfilled_at - created_at | timediff(fulfilled_at, created_at) |
+---------------------------+------------------------------------+
| 4041.000000 | 00:00:01 |
+---------------------------+------------------------------------+
I know I should be using timediff, but I'm just curious why I'm seeing this or if it's documented somewhere.
MySQL is just converting strings into numbers as best it can, so that it can do the mathematical operation on them. In this case, its just stripping out all of the non numerical colons, dashes and spaces.
Try this:
SELECT (20110413155959 - 20110413160000) AS dates;
Your dates, without all the stuff that stops them being numbers - the result is -4041
Recall that mysql has two differente kinds of datetime-related substractions: The _SUB suffix is for substracting a date minus an interval, returning a date. The _DIFF suffix is for getting the difference between two dates, returning an interval (BTW, notice that only the first one has an inverse analog: _ADD)
The +/- signs are to be used for the first one (ADD/SUB), hence MYSQL expects an interval as a second argument.
DATE = DATE_ADD(DATE,INTERVAL) Also accepts +
DATE = DATE_SUB(DATE,INTERVAL) Also accepts -
INTERVAL = DATE_DIFF(DATE,DATE )
See doc here, the bit starting from:
Date arithmetic also can be performed using INTERVAL
together with the + or - operator...
Hence, it's incorrect to use the - to take the difference between two dates. Now, MYSQL, when confronted with incorrect outputs, tries to do its best guess (instead of throwing an error), sometimes that goes well, sometimes not.