Difference between two dates in MySQL - mysql

How to calculate the difference between two dates, in the format YYYY-MM-DD hh: mm: ss and to get the result in seconds or milliseconds?

SELECT TIMEDIFF('2007-12-31 10:02:00','2007-12-30 12:01:01');
-- result: 22:00:59, the difference in HH:MM:SS format
SELECT TIMESTAMPDIFF(SECOND,'2007-12-30 12:01:01','2007-12-31 10:02:00');
-- result: 79259 the difference in seconds
So, you can use TIMESTAMPDIFF for your purpose.

If you are working with DATE columns (or can cast them as date columns), try DATEDIFF() and then multiply by 24 hours, 60 min, 60 secs (since DATEDIFF returns diff in days). From MySQL:
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
for example:
mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30 00:00:00') * 24*60*60

Get the date difference in days using DATEDIFF
SELECT DATEDIFF('2010-10-08 18:23:13', '2010-09-21 21:40:36') AS days;
+------+
| days |
+------+
| 17 |
+------+
OR
Refer the below link
MySql difference between two timestamps in days?

SELECT TIMESTAMPDIFF(HOUR,NOW(),'2013-05-15 10:23:23')
calculates difference in hour.(for days--> you have to define day replacing hour
SELECT DATEDIFF('2012-2-2','2012-2-1')
SELECT TO_DAYS ('2012-2-2')-TO_DAYS('2012-2-1')

select
unix_timestamp('2007-12-30 00:00:00') -
unix_timestamp('2007-11-30 00:00:00');

If you want to add where clause with DATEDIFF then it is also possible to add where clause or condition.
Take a look of following example.
select DATEDIFF(now(), '2022-08-12 17:55:51.000000') from properties p WHERE p.property_name = 'KEY';
Result : 6

SELECT TIMESTAMPDIFF(SECOND,'2018-01-19 14:17:15','2018-01-20 14:17:15');
Second approach
SELECT ( DATEDIFF('1993-02-20','1993-02-19')*( 24*60*60) )AS 'seccond';
CURRENT_TIME() --this will return current Date
DATEDIFF('','') --this function will return DAYS and in 1 day there are 24hh 60mm 60sec

Or, you could use TIMEDIFF function
mysql> SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');
'-00:00:00.000001'
mysql> SELECT TIMEDIFF('2008-12-31 23:59:59.000001' , '2008-12-30 01:01:01.000002');
'46:58:57.999999'

This function takes the difference between two dates and shows it in a date format yyyy-mm-dd. All you need is to execute the code below and then use the function. After executing you can use it like this
SELECT datedifference(date1, date2)
FROM ....
.
.
.
.
DELIMITER $$
CREATE FUNCTION datedifference(date1 DATE, date2 DATE) RETURNS DATE
NO SQL
BEGIN
DECLARE dif DATE;
IF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < 0 THEN
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(DATE_SUB(date1, INTERVAL 1 MONTH)), '-', DAY(date2))))),
'%Y-%m-%d');
ELSEIF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < DAY(LAST_DAY(DATE_SUB(date1, INTERVAL 1 MONTH))) THEN
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
'%Y-%m-%d');
ELSE
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
'%Y-%m-%d');
END IF;
RETURN dif;
END $$
DELIMITER;

select TO_CHAR(TRUNC(SYSDATE)+(to_date( '31-MAY-2012 12:25', 'DD-MON-YYYY HH24:MI')
- to_date( '31-MAY-2012 10:37', 'DD-MON-YYYY HH24:MI')),
'HH24:MI:SS') from dual
-- result : 01:48:00
OK it's not quite what the OP asked, but it's what I wanted to do :-)

This code calculate difference between two dates in yyyy MM dd format.
declare #StartDate datetime
declare #EndDate datetime
declare #years int
declare #months int
declare #days int
--NOTE: date of birth must be smaller than As on date,
--else it could produce wrong results
set #StartDate = '2013-12-30' --birthdate
set #EndDate = Getdate() --current datetime
--calculate years
select #years = datediff(year,#StartDate,#EndDate)
--calculate months if it's value is negative then it
--indicates after __ months; __ years will be complete
--To resolve this, we have taken a flag #MonthOverflow...
declare #monthOverflow int
select #monthOverflow = case when datediff(month,#StartDate,#EndDate) -
( datediff(year,#StartDate,#EndDate) * 12) <0 then -1 else 1 end
--decrease year by 1 if months are Overflowed
select #Years = case when #monthOverflow < 0 then #years-1 else #years end
select #months = datediff(month,#StartDate,#EndDate) - (#years * 12)
--as we do for month overflow criteria for days and hours
--& minutes logic will followed same way
declare #LastdayOfMonth int
select #LastdayOfMonth = datepart(d,DATEADD
(s,-1,DATEADD(mm, DATEDIFF(m,0,#EndDate)+1,0)))
select #days = case when #monthOverflow<0 and
DAY(#StartDate)> DAY(#EndDate)
then #LastdayOfMonth +
(datepart(d,#EndDate) - datepart(d,#StartDate) ) - 1
else datepart(d,#EndDate) - datepart(d,#StartDate) end
select
#Months=case when #days < 0 or DAY(#StartDate)> DAY(#EndDate) then #Months-1 else #Months end
Declare #lastdayAsOnDate int;
set #lastdayAsOnDate = datepart(d,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#EndDate),0)));
Declare #lastdayBirthdate int;
set #lastdayBirthdate = datepart(d,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#StartDate)+1,0)));
if (#Days < 0)
(
select #Days = case when( #lastdayBirthdate > #lastdayAsOnDate) then
#lastdayBirthdate + #Days
else
#lastdayAsOnDate + #Days
end
)
print convert(varchar,#years) + ' year(s), ' +
convert(varchar,#months) + ' month(s), ' +
convert(varchar,#days) + ' day(s) '

If you've a date stored in text field as string you can implement this code it will fetch the list of past number of days a week, a month or a year sorting:
SELECT * FROM `table` WHERE STR_TO_DATE(mydate, '%d/%m/%Y') < CURDATE() - INTERVAL 30 DAY AND STR_TO_DATE(date, '%d/%m/%Y') > CURDATE() - INTERVAL 60 DAY
//This is for a month
SELECT * FROM `table` WHERE STR_TO_DATE(mydate, '%d/%m/%Y') < CURDATE() - INTERVAL 7 DAY AND STR_TO_DATE(date, '%d/%m/%Y') > CURDATE() - INTERVAL 14 DAY
//This is for a week
%d%m%Y is your date format
This query display the record between the days you set there like: Below from last 7 days and Above from last 14 days so it would be your last week record to be display same concept is for month or year. Whatever value you're providing in below date like: below from 7-days so the other value would be its double as 14 days. What we are saying here get all records above from last 14 days and below from last 7 days. This is a week record you can change value to 30-60 days for a month and also for a year.
Thank You Hope it will help someone.

You would simply do this:
SELECT (end_time - start_time) FROM t; -- return in Millisecond
SELECT (end_time - start_time)/1000 FROM t; -- return in Second

Why not just
Select Sum(Date1 - Date2) from table
date1 and date2 are datetime

Related

Timestampdiff excluding some hours and weekend mysql [duplicate]

I have a field of time Timestamp in my MySQL database which is mapped to a DATE datatype in my bean. Now I want a query by which I can fetch all records in the database for which the difference between the current timestamp and the one stored in the database is > 20 minutes.
How can I do it?
What i want is:
SELECT * FROM MyTab T WHERE T.runTime - now > 20 minutes
Are there any MySQL functions for this, or any way to do this in SQL?
If you have MySql version above 5.6 you could use TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) something like
select * from MyTab T where
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20
MySql version >=5.6
I am using below code for today and database date.
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20
According to the documentation, the first argument can be any of the following:
MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
ROUND(time_to_sec((TIMEDIFF(NOW(), "2015-06-10 20:15:00"))) / 60);
Try this one:
select * from MyTab T where date_add(T.runTime, INTERVAL 20 MINUTE) < NOW()
NOTE: this should work if you're using MySQL DateTime format. If you're using Unix Timestamp (integer), then it would be even easier:
select * from MyTab T where UNIX_TIMESTAMP() - T.runTime > 20*60
UNIX_TIMESTAMP() function returns you current unix timestamp.
You can try this:
SELECT * FROM MyTab T WHERE CURRENT_TIMESTAMP() > T.runTime + INTERVAL 20 MINUTE;
The CURRENT_TIMESTAMP() is a function and returns the current date and time. This function works From MySQL 4.0
If you have MySql version prior than 5.6 you don't have TIMESTAMPDIFF. So,I wrote my own MySql function to do this. Accets %i or %m for minutes and %h for hours. You can extend it.
Example of usage:
SELECT MYTSDIFF('2001-01-01 10:44:32', '2001-01-01 09:50:00', '%h')
Here goes the function. Enjoy:
DROP FUNCTION IF EXISTS MYTSDIFF;
DELIMITER $$
CREATE FUNCTION `MYTSDIFF`( date1 timestamp, date2 timestamp, fmt varchar(20))
returns varchar(20) DETERMINISTIC
BEGIN
declare secs smallint(2);
declare mins smallint(2);
declare hours int;
declare total real default 0;
declare str_total varchar(20);
if date1 > DATE_ADD( date2, interval 30 day) then
return '999999.999'; /* OUT OF RANGE TIMEDIFF */
end if;
select cast( time_format( timediff(date1, date2), '%s') as signed) into secs;
select cast( time_format( timediff(date1, date2), '%i') as signed) into mins;
select cast( time_format( timediff(date1, date2), '%H') as signed) into hours;
set total = hours * 3600 + mins * 60 + secs;
set fmt = LOWER( fmt);
if fmt = '%m' or fmt = '%i' then
set total = total / 60;
elseif fmt = '%h' then
set total = total / 3600;
else
/* Do nothing, %s is the default: */
set total = total + 0;
end if;
select cast( total as char(20)) into str_total;
return str_total;
END$$
DELIMITER ;

How to find year and Month from no of days passed in sql

I have the amount of days passed , I want to find out the month and year for that particular day gap using big query SQL
For eg: I have the following fields : date_today as DATE , day_passed
as INTEGER
date_today = '2018-01-22'
day_passed = 32
From this day passed I want to create a new column like below using day_passed column value
month_joined = '2017-12'
Challenge: Months may have different days In Feb(28 or 29),30,31
What will be the best way to solve this problem?
In tsql you can use this query which I suggest you modify into a function.
declare #date nvarchar(20) = '2018-01-22'
declare #interval int = -32
declare #newDate datetime = DATEADD(DAY,#interval,CAST(#date as datetime))
select cast(year(#newDate) as nvarchar(4)) +'-'+ cast(month(#newDate) as nvarchar(2)) as 'month_joined'
To create into a function in tsql:
CREATE FUNCTION YearMonthConvert(
#Date datetime,
#Interval int = 0)
RETURNS NVARCHAR(10)
AS
BEGIN
DECLARE #newDate datetime = DATEADD(DAY,#Interval,CAST(#Date as datetime))
RETURN cast(year(#newDate) as nvarchar(4)) +'-'+ cast(month(#newDate) as nvarchar(2))
END;
then it can be called like this:
select dbo.yearmonthconvert('2018-01-22',-32)
I believe the mysql syntax is as follows - not done mysql so if anyone wants to correct me in the comments that would be much appreciated.
set #date = '2018-01-22';
set #interval = -32;
set month_joined = DATE_ADD(#date, INTERVAL #interval DAY);
Use mysql functons
DATE_SUB
or
DATE_ADD
SELECT DATE_SUB('2018-01-22', INTERVAL 32 DAY)
Result:
2017-12-21
Below is for BigQuery Standard SQL
It should give you an idea of how you can work with dates in BigQuery
#standardSQL
SELECT
date_today,
day_passed,
DATE_SUB(date_today, INTERVAL day_passed DAY) day_joined,
DATE_TRUNC(DATE_SUB(date_today, INTERVAL day_passed DAY), MONTH) month_joined_as_date,
FORMAT_DATE('%Y-%m', DATE_SUB(date_today, INTERVAL day_passed DAY)) month_joined_as_string
FROM `yourproject.yourdataset.yourtable`
you can test / play with above using dummy data from your question as below
#standardSQL
WITH `yourproject.yourdataset.yourtable` AS (
SELECT DATE '2018-01-22' date_today, 32 day_passed
)
SELECT
date_today,
day_passed,
DATE_SUB(date_today, INTERVAL day_passed DAY) day_joined,
DATE_TRUNC(DATE_SUB(date_today, INTERVAL day_passed DAY), MONTH) month_joined_as_date,
FORMAT_DATE('%Y-%m', DATE_SUB(date_today, INTERVAL day_passed DAY)) month_joined_as_string
FROM `yourproject.yourdataset.yourtable`
with result
date_today day_passed day_joined month_joined_as_date month_joined_as_string
2018-01-22 32 2017-12-21 2017-12-01 2017-12
I solved it in a simple way in bigquery
SUBSTR(STRING(DATE_ADD(DATE(date_today), -day_passed, "DAY")),1,7) AS month_joined

Changing datetime value in MySQL

What I am trying to do, is to set beginning of time interval, if that is not correctly set into stored procedure. However, it somehow does not work very well..
This is my code:
CREATE PROCEDURE intervals_generator (IN start DATETIME, IN ending DATETIME, IN intervalis INT)
BEGIN
-- temp values
DECLARE next_date DATETIME;
-- result temp values
DECLARE start_temp DATETIME;
DECLARE ending_temp DATETIME;
-- date formatting variables
DECLARE year CHAR(20);
DECLARE month CHAR(20);
DECLARE day CHAR(20);
DECLARE new_start CHAR(20);
-- SET starting date if is incorrect DATE_FORMAT(NOW(), '%d %m %Y')
SET year := DATE_FORMAT(start, '%Y');
SET month := DATE_FORMAT(start, '%c');
SET day := DATE_FORMAT(start, '%e');
IF intervalis = '1_day' THEN
BEGIN
SET new_start := year+' '+month+' '+day+' 00:00:00';
END;
ELSEIF intervalis = '1_month' THEN
BEGIN
SET new_start := year+' '+month+' 1 00:00:00';
END;
ELSEIF intervalis = '1_quarter' THEN
BEGIN
IF MONTH(start) IN (2, 3) THEN
SET month := 1;
ELSEIF MONTH(start) IN (5, 6) THEN
SET month := 4;
ELSEIF MONTH(start) IN (8, 9) THEN
SET month := 7;
ELSEIF MONTH(start) IN (11, 12) THEN
SET month := 10;
END IF;
SET new_start := year+' '+month+' 1 00:00:00';
END;
ELSEIF intervalis = '1_year' THEN
BEGIN
SET new_start := year+' 1 1 00:00:00';
END;
END IF;
SET start := STR_TO_DATE(new_start, '%Y %c %e %h:%i:%s');
SELECT year, month, day, start;
DROP TEMPORARY TABLE IF EXISTS intervals_result;
END//
DELIMITER ;
I have tried many different formattings settings and functions, but the output is still wrong, like this:
mysql> CALL intervals_generator('2013-02-01 00:00:00', '2015-12-31 00:00:00', '1_year');
+------+-------+------+---------------------+
| year | month | day | start |
+------+-------+------+---------------------+
| 2013 | 2 | 1 | 2016-00-00 00:00:00 |
+------+-------+------+---------------------+
1 row in set (0.02 sec)
Query OK, 0 rows affected, 1 warning (0.02 sec)
I really dont understand why output is "2016-00-00" instead of "2013-01-01". year, month and day variables are defined as CHAR and also function that extracts them from datetime should be returning CHAR. And function STR_TO_DATE should also been taking CHAR format, so it is a mystery for me.
If anyone has some idea, please give me hint.
If you work in DATEs instead of strings, you can make use of MySQL's date functions and operators and make everything a whole lot simpler... but not too simple because this is MySQL.
The problem with MySQL and dates is its date functionality is a real mish-mash that sometimes works with DATEs, sometimes with strings, sometimes with integers, and is missing basic functionality. It lacks a simple function to set a piece of a date; there's no function to change the MONTH part of a DATE to February. There's not even a good way to make a date from the year, month and day, closest thing you get is MAKEDATE() which takes a year and the day of the year (?!). Fortunately, DATEs in MySQL respond to math operations and it's better than messing with strings.
If you have, for example, 2013-02-12 and want 2013-02-01 you have to first make a new date with just the year using MAKEDATE, then add the month part.
-- 2013-01-01
SET new_date := MAKEDATE(YEAR(old_date), 1);
-- 2013-02-01
-- Since MONTH returns from 1 to 12, you need to take away one.
SET new_date := new_date + (INTERVAL MONTH(old_date) - 1) MONTH;
After chopping out all the unused variables, changing to date math, and using the CASE statement instead of a big IF/ELSE chain, we get this:
CREATE PROCEDURE intervals_generator (IN start_date DATE, IN intervals TEXT)
BEGIN
DECLARE new_start DATE;
CASE intervals
WHEN '1_day' THEN
-- Nothing to do, DATE has already truncated the time portion.
SET new_start := start_date;
WHEN '1_month' THEN
-- Set to the year and month of the start date
SET new_start := MAKEDATE(YEAR(start_date), 1) + INTERVAL (MONTH(start_date) - 1) MONTH;
WHEN '1_quarter' THEN
BEGIN
-- Set to the year and month of the start date
SET new_start := MAKEDATE(YEAR(start_date), 1) + INTERVAL (MONTH(start_date) - 1) MONTH;
-- Subtract the necessary months for the beginning of the quarter
SET new_start := new_start - INTERVAL (MONTH(new_start) - 1) % 3 MONTH;
END;
WHEN '1_year' THEN
-- Set the date to the first day of the year
SET new_start := MAKEDATE(YEAR(start_date), 1);
END CASE;
SELECT new_start;
END//
Try it out.
This statement is not doing what you expect:
SET new_start := year+' '+month+' '+day+' 00:00:00';
In MySQL, the + operator does addition. That's it, not concatenation.
I think you intend:
SET new_start := concat(year, ' ', month, ' ', day, ' 00:00:00');
I haven't looked at the rest of the logic to see if it makes sense, but this is one glaring problem.
Instead of slicing and building new date from parts(concatenating) which is error-prone you can use built-in DATE_FORMAT:
SqlFiddleDemo
SET #date = '2013-05-03 10:05:00';
SELECT CAST(#date AS DATETIME) AS Date,
DATE_FORMAT(#date ,'%Y-01-01 00:00:00') AS Year_Allign,
CASE EXTRACT(QUARTER FROM #date)
WHEN 1 THEN DATE_FORMAT(#date ,'%Y-01-01 00:00:00')
WHEN 2 THEN DATE_FORMAT(#date ,'%Y-04-01 00:00:00')
WHEN 3 THEN DATE_FORMAT(#date ,'%Y-07-01 00:00:00')
WHEN 4 THEN DATE_FORMAT(#date ,'%Y-10-01 00:00:00')
ELSE NULL END AS Quarter_Allign,
DATE_FORMAT(#date ,'%Y-%m-01 00:00:00') AS Month_Allign,
DATE_FORMAT(#date ,'%Y-%m-%d 00:00:00') AS Day_Allign;
SqlFiddleDemo2
SET #date = '2013-05-03 10:05:00';
SET #allign = '1_QUARTER';
SELECT
CAST(#date AS DATETIME) AS Date,
CASE #allign
WHEN '1_YEAR' THEN DATE_FORMAT(#date ,'%Y-01-01 00:00:00')
WHEN '1_QUARTER' THEN (CASE EXTRACT(QUARTER FROM #date)
WHEN 1 THEN DATE_FORMAT(#date ,'%Y-01-01 00:00:00')
WHEN 2 THEN DATE_FORMAT(#date ,'%Y-04-01 00:00:00')
WHEN 3 THEN DATE_FORMAT(#date ,'%Y-07-01 00:00:00')
WHEN 4 THEN DATE_FORMAT(#date ,'%Y-10-01 00:00:00')
ELSE NULL END)
WHEN '1_MONTH' THEN DATE_FORMAT(#date ,'%Y-%m-01 00:00:00')
WHEN '1_DAY' THEN DATE_FORMAT(#date ,'%Y-%m-%d 00:00:00')
ELSE NULL
END AS Alligned;

SQL Server - calculate elapsed time between two datetime stamps in HH:MM:SS format

I have a SQL Server table that has a "Time" column. The table is a log table the houses status messages and timestamps for each message. The log table is inserted into via a batch file. There is an ID column that groups rows together. Each time the batch file runs it initializes the ID and writes records. What I need to do is get the elapsed time from the first record in an ID set to the last record of the same ID set. I started toying with select Max(Time) - Min(Time) from logTable where id = but couldn't figure out how to format it correctly. I need it in HH:MM:SS.
SQL Server doesn't support the SQL standard interval data type. Your best bet is to calculate the difference in seconds, and use a function to format the result. The native function CONVERT() might appear to work fine as long as your interval is less than 24 hours. But CONVERT() isn't a good solution for this.
create table test (
id integer not null,
ts datetime not null
);
insert into test values (1, '2012-01-01 08:00');
insert into test values (1, '2012-01-01 09:00');
insert into test values (1, '2012-01-01 08:30');
insert into test values (2, '2012-01-01 08:30');
insert into test values (2, '2012-01-01 10:30');
insert into test values (2, '2012-01-01 09:00');
insert into test values (3, '2012-01-01 09:00');
insert into test values (3, '2012-01-02 12:00');
Values were chosen in such a way that for
id = 1, elapsed time is 1 hour
id = 2, elapsed time is 2 hours, and
id = 3, elapsed time is 3 hours.
This SELECT statement includes one column that calculates seconds, and one that uses CONVERT() with subtraction.
select t.id,
min(ts) start_time,
max(ts) end_time,
datediff(second, min(ts),max(ts)) elapsed_sec,
convert(varchar, max(ts) - min(ts), 108) do_not_use
from test t
group by t.id;
ID START_TIME END_TIME ELAPSED_SEC DO_NOT_USE
1 January, 01 2012 08:00:00 January, 01 2012 09:00:00 3600 01:00:00
2 January, 01 2012 08:30:00 January, 01 2012 10:30:00 7200 02:00:00
3 January, 01 2012 09:00:00 January, 02 2012 12:00:00 97200 03:00:00
Note the misleading "03:00:00" for the 27-hour difference on id number 3.
Function to format elapsed time in SQL Server
UPDATED:
Correctly calculate a timespan in SQL Server, even if more than 24 hours:
-- Setup test data
declare #minDate datetime = '2012-12-12 20:16:47.160'
declare #maxDate datetime = '2012-12-13 15:10:12.050'
-- Get timespan in hh:mi:ss
select cast(
(cast(cast(#maxDate as float) - cast(#minDate as float) as int) * 24) /* hours over 24 */
+ datepart(hh, #maxDate - #minDate) /* hours */
as varchar(10))
+ ':' + right('0' + cast(datepart(mi, #maxDate - #minDate) as varchar(2)), 2) /* minutes */
+ ':' + right('0' + cast(datepart(ss, #maxDate - #minDate) as varchar(2)), 2) /* seconds */
-- Returns 18:53:24
Edge cases that show inaccuracy are especially welcome!
DECLARE #EndTime AS DATETIME, #StartTime AS DATETIME
SELECT #StartTime = '2013-03-08 08:00:00', #EndTime = '2013-03-08 08:30:00'
SELECT CAST(#EndTime - #StartTime AS TIME)
Result: 00:30:00.0000000
Format result as you see fit.
The best and simple way:
Convert(varchar, {EndTime} - {StartTime}, 108)
Just like Anri noted.
Use the DATEDIFF to return value in milliseconds, seconds, minutes, hours, ...
DATEDIFF(interval, date1, date2)
interval REQUIRED - The time/date part to return. Can be one of the following values:
year, yyyy, yy = Year
quarter, qq, q = Quarter
month, mm, m = month
dayofyear = Day of the year
day, dy, y = Day
week, ww, wk = Week
weekday, dw, w = Weekday
hour, hh = hour
minute, mi, n = Minute
second, ss, s = Second
millisecond, ms = Millisecond
date1, date2 REQUIRED - The two dates to calculate the difference between
select convert(varchar, Max(Time) - Min(Time) , 108) from logTable where id=...
See if this helps. I can set variables for Elapsed Days, Hours, Minutes, Seconds.
You can format this to your liking or include in a user defined function.
Note: Don't use DateDiff(hh,#Date1,#Date2). It is not reliable! It rounds in unpredictable ways
Given two dates...
(Sample Dates: two days, three hours, 10 minutes, 30 seconds difference)
declare #Date1 datetime = '2013-03-08 08:00:00'
declare #Date2 datetime = '2013-03-10 11:10:30'
declare #Days decimal
declare #Hours decimal
declare #Minutes decimal
declare #Seconds decimal
select #Days = DATEDIFF(ss,#Date1,#Date2)/60/60/24 --Days
declare #RemainderDate as datetime = #Date2 - #Days
select #Hours = datediff(ss, #Date1, #RemainderDate)/60/60 --Hours
set #RemainderDate = #RemainderDate - (#Hours/24.0)
select #Minutes = datediff(ss, #Date1, #RemainderDate)/60 --Minutes
set #RemainderDate = #RemainderDate - (#Minutes/24.0/60)
select #Seconds = DATEDIFF(SS, #Date1, #RemainderDate)
select #Days as ElapsedDays, #Hours as ElapsedHours, #Minutes as ElapsedMinutes, #Seconds as ElapsedSeconds
Hope this helps you in getting the exact time between two time stamps
Create PROC TimeDurationbetween2times(#iTime as time,#oTime as time)
As
Begin
DECLARE #Dh int, #Dm int, #Ds int ,#Im int, #Om int, #Is int,#Os int
SET #Im=DATEPART(MI,#iTime)
SET #Om=DATEPART(MI,#oTime)
SET #Is=DATEPART(SS,#iTime)
SET #Os=DATEPART(SS,#oTime)
SET #Dh=DATEDIFF(hh,#iTime,#oTime)
SET #Dm = DATEDIFF(mi,#iTime,#oTime)
SET #Ds = DATEDIFF(ss,#iTime,#oTime)
DECLARE #HH as int, #MI as int, #SS as int
if(#Im>#Om)
begin
SET #Dh=#Dh-1
end
if(#Is>#Os)
begin
SET #Dm=#Dm-1
end
SET #HH = #Dh
SET #MI = #Dm-(60*#HH)
SET #SS = #Ds-(60*#Dm)
DECLARE #hrsWkd as varchar(8)
SET #hrsWkd = cast(#HH as char(2))+':'+cast(#MI as char(2))+':'+cast(#SS as char(2))
select #hrsWkd as TimeDuration
End

Calculating time difference between 2 dates in minutes

I have a field of time Timestamp in my MySQL database which is mapped to a DATE datatype in my bean. Now I want a query by which I can fetch all records in the database for which the difference between the current timestamp and the one stored in the database is > 20 minutes.
How can I do it?
What i want is:
SELECT * FROM MyTab T WHERE T.runTime - now > 20 minutes
Are there any MySQL functions for this, or any way to do this in SQL?
If you have MySql version above 5.6 you could use TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) something like
select * from MyTab T where
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20
MySql version >=5.6
I am using below code for today and database date.
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20
According to the documentation, the first argument can be any of the following:
MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
ROUND(time_to_sec((TIMEDIFF(NOW(), "2015-06-10 20:15:00"))) / 60);
Try this one:
select * from MyTab T where date_add(T.runTime, INTERVAL 20 MINUTE) < NOW()
NOTE: this should work if you're using MySQL DateTime format. If you're using Unix Timestamp (integer), then it would be even easier:
select * from MyTab T where UNIX_TIMESTAMP() - T.runTime > 20*60
UNIX_TIMESTAMP() function returns you current unix timestamp.
You can try this:
SELECT * FROM MyTab T WHERE CURRENT_TIMESTAMP() > T.runTime + INTERVAL 20 MINUTE;
The CURRENT_TIMESTAMP() is a function and returns the current date and time. This function works From MySQL 4.0
If you have MySql version prior than 5.6 you don't have TIMESTAMPDIFF. So,I wrote my own MySql function to do this. Accets %i or %m for minutes and %h for hours. You can extend it.
Example of usage:
SELECT MYTSDIFF('2001-01-01 10:44:32', '2001-01-01 09:50:00', '%h')
Here goes the function. Enjoy:
DROP FUNCTION IF EXISTS MYTSDIFF;
DELIMITER $$
CREATE FUNCTION `MYTSDIFF`( date1 timestamp, date2 timestamp, fmt varchar(20))
returns varchar(20) DETERMINISTIC
BEGIN
declare secs smallint(2);
declare mins smallint(2);
declare hours int;
declare total real default 0;
declare str_total varchar(20);
if date1 > DATE_ADD( date2, interval 30 day) then
return '999999.999'; /* OUT OF RANGE TIMEDIFF */
end if;
select cast( time_format( timediff(date1, date2), '%s') as signed) into secs;
select cast( time_format( timediff(date1, date2), '%i') as signed) into mins;
select cast( time_format( timediff(date1, date2), '%H') as signed) into hours;
set total = hours * 3600 + mins * 60 + secs;
set fmt = LOWER( fmt);
if fmt = '%m' or fmt = '%i' then
set total = total / 60;
elseif fmt = '%h' then
set total = total / 3600;
else
/* Do nothing, %s is the default: */
set total = total + 0;
end if;
select cast( total as char(20)) into str_total;
return str_total;
END$$
DELIMITER ;