I need to calculated difference in seconds between 2 dates. I cannot use TIMEDIFF because of its limitations.
When I use:
SELECT UNIX_TIMESTAMP('2015-03-28 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
it returns expected 86400 seconds (what gives 24 hours) but when I use:
SELECT UNIX_TIMESTAMP('2015-03-29 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
it seems it doesn't give 86400*2 but 169200 instead what gives 47 hours.
The question is - why is that? Is it a bug or feature? Is there any other reasonable way to calculate time difference not worrying about time limitations?
It looks like that in 2015 there was Daylight changing at 29 March, it could be the reason
Daylight saving 2015
There are a couple of ways in which this problem can be tackled:
With UNIX_TIMESTAMP():
Use SET SESSION time_zone = '+0:00' before carrying out date operations.
SET SESSION time_zone = '+0:00';
SELECT UNIX_TIMESTAMP('2015-03-29 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
This returns 172800, i.e. a proper time difference of 48 hours.
Demo.
With TIMESTAMPDIFF():
If you don't wish to use SET SESSION time_zone, you could try TIMESTAMPDIFF()
SELECT UNIX_TIMESTAMP('2015-03-29 08:21:15') - UNIX_TIMESTAMP('2015-03-27 08:21:15');
SELECT TIMESTAMPDIFF(SECOND, '2015-03-27 08:21:15', '2015-03-29 08:21:15');
The first computation results in 169200 (i.e. 47 hours) and the second shows 172800 (i.e. 48 hours).
Remember though that the smaller timestamp should be used first in TIMESTAMPDIFF(), or you'd get a negative result. Alternatively, you could wrap TIMESTAMPDIFF() under ABS() as so:
SELECT ABS(TIMESTAMPDIFF(SECOND, '2015-03-29 08:21:15', '2015-03-27 08:21:15'));
Rextester link.
Related
how can i find the difference between two dateTime store in a MySQL database
e.g the difference in hours between 2016-03-09 04:30:00 and 2016-03-10 03:00:00.
i have tried dateDiff() but it does not compare the hours that is need to see the difference between (2016-03-09 04:30:00) - (2016-03-10 03:10:00).
the order is year-month-day time
The output i need is the number of hours between these times also considering the time as well.
You can use TIMESTAMPDIFF to find the difference between two timestamps
SELECT TIMESTAMPDIFF(HOUR,'2009-05-18 10:00','2009-05-18 11:00');
If you want fraction(eg: 1.5 hrs) hours you can do like below
SELECT (UNIX_TIMESTAMP('2012-10-30 10:40')-UNIX_TIMESTAMP('2012-10-30 10:30'))/3600 hour_diff
One simple method is to use to_seconds():
select to_seconds(dt1) - to_seconds(dt2)
This gives the difference in seconds. Then you can divide by 60*60 to get hours or 24*60*60 for days.
I'm new for mysql, Already value in time field, I want to update extra 5 minutes in time field using query. I tried so many things but not working.
Here my query:
UPDATE STUDENT SET START_TIME = ADDTIME(START_TIME, 500) WHERE ID = 1;
Above query working but one issue is there that is, If my field having 23:55:00.
I want result after executing query 00:00:00 but it updates 24:00:00.
Anyone help me!
Thanks in advance!!
This is bit tricky, because you only have the time, and you want it to wrap around to 0 after hitting 24 hours. My approach is to extract the number of seconds from START_DATE, add 5 minutes, then take the mod of this by 24 hours to wrap around to zero if it exceeds one day's worth of seconds.
UPDATE STUDENT
SET START_TIME = CAST(STR_TO_DATE(CAST(MOD((TIME_TO_SEC(START_TIME) + 300), 86400) AS CHAR(5)), '%s') AS TIME)
WHERE ID = 1
In the demo below, you can see the logic in action which correctly converts 23:55:00 with five minutes added to become 00:00:00.
SQLFiddle
However, the easiest solution in your case might be to just use a DATETIME and ignore the date component. Then the time should wrap automatically to a new day.
select addtime('23:55:00', '00:06:00');
output - 24:01:00 (Ideally it is right, because time datatype represents only time, if it converts to 00:01:00 then time component looses 24hr, which is wrong)
select addtime('2016-09-01 23:55:00', '00:06:00');
output - 2016-09-02 00:01:00 (In this case, 24hr gets added in date so time component is represented as 00:01:00)
If the requirement is to get it as 00:01:00 then here is the workaround -
SELECT TIME((ADDTIME(TIME('23:59:59'), TIME('02:00:00')))%(TIME('24:00:00')));
reference -
ADDTIME() return 24 hour time
SELECT *
FROM tablename
WHERE
MAKETIME(3,0,0) BETWEEN MAKETIME(23,0,0) AND MAKETIME(5,0,0)
is returning nothing And 3:00 is between 23:00 AND 5:00 time. Why is that can anyone explain me how to solve this problem?
It's unclear what you're actually trying to do here, because even if 3 were between 5 and 23 your query would simply return every record in the table.
SELECT MAKETIME(3,0,0) BETWEEN MAKETIME(5,0,0) AND MAKETIME(23,0,0)
Returns 0, because 3 is not between 5 and 23.
SELECT MAKETIME(5,0,0) BETWEEN MAKETIME(3,0,0) AND MAKETIME(23,0,0)
Returns 1, because 5 is between 3 and 23.
Demo: SQL Fiddle
Presumably you're trying to wrap into the previous day, in which case you can directly compare datetime values, but it's unclear given your question what fields/datatypes you're actually working with.
Update:
Based on your comment, I think you want 2 comparisons. 3 is not between 5 and 23, because time doesn't wrap across days. But if you only care about the time portion you can handle it like this:
SELECT *
FROM tablename
WHERE YourTime BETWEEN MAKETIME(23,0,0) AND MAKETIME(23,59,59)
OR YourTime BETWEEN MAKETIME(0,0,0) AND MAKETIME(5,0,0)
Remember that BETWEEN is inclusive, so if 5am is your cutoff time you may want it to be MAKETIME(4,59,59) so it includes 4:59 but not 5:00
Function MAKETIME returns a time value calculated from the hour, minute, and second arguments:
mysql> SELECT MAKETIME(3,0,0),MAKETIME(23,0,0),MAKETIME(5,0,0)
-> '03:00:00', '23:00:00', '05:00:00'
and, of course, 3 is not BETWEEN 23 AND 5 and it will return false. But yes, 3AM actually is between 11PM and 5AM, so how could you solve this?
Let's consider 23 as your START_TIME, and 5 as your END_TIME.
Since START_TIME has to happen before END_TIME, if this is not the case (23>5) that means that the interval rolls over the next day.
I would try with a query like this:
SELECT *
FROM yourtable
WHERE
(MAKETIME(START_TIME,0,0)<=MAKETIME(END_TIME,0,0) AND MAKETIME(3,0,0) BETWEEN MAKETIME(START_TIME,0,0) AND MAKETIME(END_TIME,0,0))
OR
(MAKETIME(START_TIME,0,0)>MAKETIME(END_TIME,0,0) AND NOT (MAKETIME(3,0,0) BETWEEN MAKETIME(START_TIME,0,0) AND MAKETIME(END_TIME,0,0)))
This must return 1440 minutes and is working fine:
select abs(round((TIME_TO_SEC(TIMEDIFF('2013-03-13 10:00',
'2013-03-14 10:00'))/60),2)) ;
(2) same function date changed to 2 years days this returns 50339.98
select abs(round((TIME_TO_SEC(TIMEDIFF('2013-03-12 10:00',
'2013-03-14 10:00'))/60),2)) ;
(3) same function with date changed to 4 years days and the answer is 50339.98
select abs(round((TIME_TO_SEC(TIMEDIFF('2013-03-10 10:00',
'2013-03-14 10:00'))/60),2)) ;
Is this a bug?
This must return 1440 minutes and is working fine:
No. There could be a daylight saving change or a leap second change. You can't depend on two times being offset by a certain amount just because you think they should be.
There was something that was odd.
select
TIMEDIFF('2000-09-14 09:00', '2000-08-10 10:00'),
TIMESTAMPDIFF(SECOND, '2000-09-14 09:00', '2000-08-10 10:00');
Gives
838:59:59, -3020400
Which is not possible. The explanation is that TIME values in MySQL have a limit on acceptable values.
MySQL retrieves and displays TIME values in 'HH:MM:SS' format (or
'HHH:MM:SS' format for large hours values). TIME values may range from
'-838:59:59' to '838:59:59'.
Apparently you should either use one of the functions TIMESTAMPDIFF() and UNIX_TIMESTAMP(), both of which return integers, or use DATEDIFF() if you have actual dates.
I have complicated query over very big table.
Long story short, when I use convert time to select period of day (let's say 12-13h, converting it from datetime row) query takes few minutes, instead of few seconds without convert!
So, I tried datepart, and it works well, almost instant, but, problem is, how to point to hours and minutes in same time?
Any other fast solution is more than welcome.
Thanks.
Meanwhile I came up with this:
DATEPART(HOUR, datetimecolumn)*100 + DATEPART(MINUTE, datetimecolumn)) between 1210 and 1540
You can use datePart if you are willing to do a bit of math, as shown below:
12:10 = 12 * 60 + 10 = 730 minutes
15:40 = 15 * 60 + 40 = 940 minutes
select * .....
where datepart(mi, datefield) between (12*60+10) and (15*60+40)
If you have a constant periods - i.e. - always hourly and no any floating periods - you may introduce something like "ordinal number of period" calculated field, index on it and query of it with precalculated period value
OR
is there are no any constant periods - try to calculate proper begin and end values prior to SELECT statement and use them in the query.
Keep in mind that using functions in where clause of query - sometimes is a bad idea. Using functions in ORDER BY clause - always bad
You can get GETTIME from following Function
alter function GetTimeOnly(#_DateTime DateTime)
returns datetime
as
begin
return dateadd(day, -datediff(day, 0, #_datetime), #_datetime)
end
go
OR YOU CAN HAVE THE TIME FROM CONVERT FUNCTION.
SELECT
CONVERT(VARCHAR(8),GETDATE(),108) AS HourMinuteSecond,
CONVERT(VARCHAR(8),GETDATE(),101) AS DateOnly