Related
My start and finish columns are in the format Yyyy-mm-dd HH:mm:ss.ms I want the difference between the two in HH:mm:ss.ms format. How do I go about this?
My query looks like this:
select *, convert(time,
Dateadd(s,
Datediff(s, A.Finish, A.Start),
Cast('1900-01-01 00:00:00.000000' as datetime2)
)
) as dif
from (
select *,
dateadd(s,convert(int,left(start,10)),'1970-01-01') as Start,
dateadd(s,convert(int,left(finish,10)),'1970-01-01') as Finish,
from tableB
) A
order by dif asc
I've converted unix time stamps to standard format in inner query. When I run this the start date and start time appear as '2019-12-11 15:45:20.000' and '2019-12-12 15:45:17.000' but my dif appears as '00:00:03',which is wrong.
Any help would be appreciated
I have used two sources to try to help you:
https://www.rodolforodarte.com/2011/05/using-datediff-to-display-hhmmss/
AND
Show datediff as seconds, milliseconds
Here is my result code:
DECLARE #START_DATE DATETIME
DECLARE #END_DATE DATETIME
SET #START_DATE = '2011-01-01 16:00:22.000'
SET #END_DATE = '2011-01-01 22:47:21.022'
SELECT CONVERT(varchar(6), DATEDIFF(MILLISECOND, #START_DATE, #END_DATE)/3600000)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), (DATEDIFF(MILLISECOND, #START_DATE, #END_DATE) % 3600000) / 60000), 2)
+ ':'
+ RIGHT('0' + CONVERT(varchar(2), ((DATEDIFF(MILLISECOND, #START_DATE, #END_DATE) % 3600000) % 60000) / 1000), 2)
+ ':'
+ RIGHT('000' + CONVERT(varchar(2), (((DATEDIFF(MILLISECOND, #START_DATE, #END_DATE) % 3600000) % 60000) % 1000)), 3) AS 'HH:MM:SS:MS'
And here is a small demo
I have an existing SQL Server table Employees with 3 columns month, year and day as date parts.
Now I have added a new column createdate where I want to insert date as a combination of all 3 columns from the current row.
UPDATE Employees
SET createdate = TRY_PARSE(CAST([year] AS VARCHAR(4)) + '/' + CAST([month] AS VARCHAR(2)) + '/' + CAST([day] AS VARCHAR(2)) AS DATETIME)
If you have invalid data in Month Or Year Or Day Colunm, then above query will update with NULL Value.
NOTE: Try_Parse will work from Sql Server Version 2012 onwards.
You can as the below:
UPDATE Employees
SET createdate = CAST(CAST(year AS VARCHAR(4)) + '.' + CAST(month AS VARCHAR(2)) + '.' + CAST(day AS VARCHAR(2)) AS DATETIME)
You can use DATEFROMPARTS very simple to form date
UPDATE Employees SET CreateDate =DATEFROMPARTS ( year, month, day )
Try this, it's update for all rows :
UPDATE Employees SET CreateDate = [day] +'/'+ [Month] +'/'+ [year]
1)...UPDATE Employees
set createdate =
CAST(
CAST(year AS VARCHAR(4)) +
RIGHT('0' + CAST(month AS VARCHAR(2)), 2) +
RIGHT('0' + CAST(day AS VARCHAR(2)), 2)
AS DATETIME)
2)...SELECT
DATEADD(year, [year]-1900, DATEADD(month, [month]-1, DATEADD(day, [day]-1, 0)))
FROM
dbo.Table
UPDATE emp SET CreateDate =( SELECT CONVERT(DATE,CAST([Year] AS VARCHAR(4))+'-'+
CAST([Month] AS VARCHAR(2))+'-'+
CAST([Day] AS VARCHAR(2))))
or
you can also use this code:
UPDATE empl SET CreateDate =( SELECT CONVERT(varchar(10),
CAST([Month] AS VARCHAR(2))+'-'+
CAST([Day] AS VARCHAR(2))+'-'+CAST([Year] AS VARCHAR(4)),101))
I have datetime column value below
2015-01-04 20:37:00.000
I tried below
cast(cast(MyDateColumn as date) as datetime)+cast(datepart(hour,MyDateColumn ) as float)/24
as MyDateColumn
and
CAST(CONVERT(CHAR(16),MyDateColumn,113) AS datetime) as MyDateColumn
These are did not work for me
How can i get above datetime as 01-04.2015 20:37 ?
Since MS SQL 2012, you can use FORMAT,
SELECT FORMAT([MyDateColumn], 'dd-MM.yyyy HH:mm')
In MYSQL it will work
SELECT DATE_FORMAT(date, '%Y-%m-%d %H:%i') AS formated_date FROM table;
In MS SQL It will work
SELECT FORMAT(getdate(), 'dd-mm-yyyy HH:mm')
In SQL Server this will work:
DECLARE #now [datetime];
SET #now = GETDATE();
SELECT
CONVERT([varchar](10), #now, 105) + ' ' +
RIGHT('0' + CONVERT([varchar](2), DATEPART(HOUR, #now)), 2) + ':' +
RIGHT('0' + CONVERT([varchar](2), DATEPART(MINUTE, #now)), 2);
In SQL Server this should do the trick:
declare #dt datetime = '2015-01-04 20:37:00.000'
select right('0' + cast(DATEPART(MM, #dt) as varchar), 2) + '-'
+ right('0' +cast(DATEPART(DAY, #dt) as varchar), 2) + '.'
+ cast(DATEPART(YEAR, #dt) as varchar) + ' '
+ right('0' +cast(DATEPART(HOUR, #dt) as varchar), 2) + ':'
+ right('0' +cast(DATEPART(MINUTE, #dt) as varchar), 2)
Simply,
SELECT CAST(CONVERT(varchar, GETDATE(), 100) as datetime)
Here's another way and you get a datetime in return.
SELECT DATEADD(
MILLISECOND,
DATEPART(MILLISECOND, '2016-02-16 13:45:24.573') * -1,
DATEADD(SECOND, DATEPART(SECOND,'2016-02-16 13:45:24.573') * -1,
'2016-02-16 13:45:24.573')
)
this is the way i do it. I needed to get -2 minutes
select CONVERT(datetime, CONVERT(CHAR(18), DATEADD(minute, -2, getdate()) , 113) + '00')
Format(Cast(Convert(varchar(15),Cast(timeval as Time),100) as DateTime),'hh:mm tt') As newtime
This will remove seconds from time as well as add AM,PM with time.
I produce a CSV file but cannot figure out the proper date format.
I am aware of the MSDN site codes for datetime conversions:
http://msdn.microsoft.com/en-us/library/ms187928.aspx
It seems there is no code to convert my datetime into this format:
MM/DD/YYYY HH:MMAM
e.g.:
12/28/2014 4:33AM
How do you achieve such format?
Platform:
Microsoft SQL server 2008
SELECT CONVERT(VARCHAR(10), GETDATE(), 101) +
RIGHT(CONVERT(VARCHAR, GETDATE(), 100), 7)
This is what you can use and is probably the most straightforward:
SELECT
RIGHT('0' + cast(month(dateColumn) AS NVARCHAR(2)), 2) + '/' -- generate the day
+ RIGHT('0' + cast(day(dateColumn) AS NVARCHAR(2)), 2) + '/' -- generate the month
+ cast(year(dateColumn) AS NVARCHAR(4)) + ' ' -- generate the year
+ convert(VARCHAR, cast(dateColumn AS TIME)), 100) -- generate the time
FROM TABLE
SELECT CONVERT(VARCHAR, GetDate(), 101) + ' ' +
CONVERT(VARCHAR, DATEPART(hh, GetDate())) + ':' +
RIGHT('0' + CONVERT(VARCHAR, DATEPART(mi, GetDate())), 2) AS TIME
EDIT: This gets the AM/PM also
SELECT CONVERT(CHAR(11),GETDATE(),101)
+ CONVERT(CHAR( 5),GETDATE(),114)
+ RIGHT(CONVERT(CHAR( 5),GETDATE(),109), 2)
SELECT CONVERT(VARCHAR(10),GETDATE(),3) as 'dd/MM/yy'
SELECT CONVERT(VARCHAR(10),GETDATE(),103) as 'dd/MM/yyyy'
SELECT CONVERT(VARCHAR(10),GETDATE(),4) as 'dd.MM.yy'
SELECT CONVERT(VARCHAR(10),GETDATE(),104) as 'dd.MM.yyyy'
SELECT CONVERT(VARCHAR(10),GETDATE(),5) as 'dd-MM-yy'
SELECT CONVERT(VARCHAR(10),GETDATE(),105) as 'dd-MM-yyyy'
SELECT CONVERT(VARCHAR(10),GETDATE(),6) as 'ddMonthyy'
SELECT CONVERT(VARCHAR(10),GETDATE(),106) as 'ddMonthyyyy'
SELECT CONVERT(VARCHAR(10),GETDATE(),7) as 'Monthdd.yy'
SELECT CONVERT(VARCHAR(10),GETDATE(),107) as 'Monthdd.yyyy'
SELECT CONVERT(VARCHAR(10),GETDATE(),8) as 'hh.mm.ss'
SELECT CONVERT(VARCHAR(10),GETDATE(),108) as 'hh.mm.ss'
SELECT CONVERT(VARCHAR(100),GETDATE(),9) as 'Monthddyy hh.mm.ss.mss'
SELECT CONVERT(VARCHAR(100),GETDATE(),109) as 'Monthddyyyy hh.mm.ss.mss'
SELECT CONVERT(VARCHAR(100),GETDATE(),10) as 'mm-dd-yy'
SELECT CONVERT(VARCHAR(100),GETDATE(),110) as 'mm-dd-yyyy'
SELECT CONVERT(VARCHAR(100),GETDATE(),11) as 'yy/MM/dd'
SELECT CONVERT(VARCHAR(100),GETDATE(),111) as 'yyyy/MM/dd'
SELECT CONVERT(VARCHAR(100),GETDATE(),12) as 'yyMMdd'
SELECT CONVERT(VARCHAR(100),GETDATE(),112) as 'yyyyMMdd'
SELECT CONVERT(VARCHAR(100),GETDATE(),13) as 'ddMonthyy hh.mm.ss.mss'
SELECT CONVERT(VARCHAR(100),GETDATE(),113) as 'ddMonthyyyy hh.mm.ss.mss'
I need to calculate the total length in terms of Hours, Minutes, Seconds, and the average length, given some data with start time and end time.
For example the result must be something like 45:15:10 which means 45 hours 15 min 10 sec, or 30:07 for 30 min 07 sec.
We're using SQL Server 2008 R2 and the conversion failed when time is more than 24:59:59. Any idea of how I could do this?
For information, the columns in the table are Id, StartDateTime, EndDateTime, etc. I need to make a monthly report which contains the recordings count of the month, the total length of these records, and the average length. I'd like to know if there is an easy way to perform all of this.
You shouldn't be converting to time - it is meant to store a point in time on a single 24h clock, not a duration or interval (even one that is constrained on its own to < 24 hours, which clearly your data is not). Instead you can take the datediff in the smallest interval required (in your case, seconds), and then perform some math and string manipulation to present it in the output format you need (it might also be preferable to return the seconds to the application or report tool and have it do this work).
DECLARE #d TABLE
(
id INT IDENTITY(1,1),
StartDateTime DATETIME,
EndDateTime DATETIME
);
INSERT #d(StartDateTime, EndDateTime) VALUES
(DATEADD(DAY, -2, GETDATE()), DATEADD(MINUTE, 15, GETDATE())),
(GETDATE() , DATEADD(MINUTE, 22, GETDATE())),
(DATEADD(DAY, -1, GETDATE()), DATEADD(MINUTE, 5, GETDATE())),
(DATEADD(DAY, -4, GETDATE()), DATEADD(SECOND, 14, GETDATE()));
;WITH x AS (SELECT id, StartDateTime, EndDateTime,
d = DATEDIFF(SECOND, StartDateTime, EndDateTime),
a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER()
FROM #d
)
SELECT id, StartDateTime, EndDateTime,
[delta_HH:MM:SS] = CONVERT(VARCHAR(5), d/60/60)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2),
[avg_HH:MM:SS] = CONVERT(VARCHAR(5), a/60/60)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2)
FROM x;
Results:
id StartDateTime EndDateTime delta_HH:MM:SS avg_HH:MM:SS
-- ------------------- ------------------- -------------- ------------
1 2013-01-19 14:24:46 2013-01-21 14:39:46 48:15:00 42:10:33
2 2013-01-21 14:24:46 2013-01-21 14:46:46 0:22:00 42:10:33
3 2013-01-20 14:24:46 2013-01-21 14:29:46 24:05:00 42:10:33
4 2013-01-17 14:24:46 2013-01-21 14:25:00 96:00:14 42:10:33
This isn't precisely what you asked for, as it won't show just MM:SS for deltas < 1 hour. You can adjust that with a simple CASE expression:
;WITH x AS (SELECT id, StartDateTime, EndDateTime,
d = DATEDIFF(SECOND, StartDateTime, EndDateTime),
a = AVG(DATEDIFF(SECOND, StartDateTime, EndDateTime)) OVER()
FROM #d
)
SELECT id, StartDateTime, EndDateTime,
[delta_HH:MM:SS] = CASE WHEN d >= 3600 THEN
CONVERT(VARCHAR(5), d/60/60) + ':' ELSE '' END
+ RIGHT('0' + CONVERT(VARCHAR(2), d/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), d % 60), 2),
[avg_HH:MM:SS] = CASE WHEN a >= 3600 THEN
CONVERT(VARCHAR(5), a/60/60) + ':' ELSE '' END
+ RIGHT('0' + CONVERT(VARCHAR(2), a/60%60), 2)
+ ':' + RIGHT('0' + CONVERT(VARCHAR(2), a % 60), 2)
FROM x;
This query changes the delta column in the 2nd row in the above result from 0:22:00 to 22:00.
I slightly modified Avinash's answer as it may end with error if difference is too big. If you need only HH:mm:ss it is sufficient to distinguish at seconds level ony like this:
SELECT CONVERT(time,
DATEADD(s,
DATEDIFF(s,
'2018-01-07 09:53:00',
'2018-01-07 11:53:01'),
CAST('1900-01-01 00:00:00.0000000' as datetime2)
)
)
SELECT CONVERT(time,
DATEADD(mcs,
DATEDIFF(mcs,
'2007-05-07 09:53:00.0273335',
'2007-05-07 09:53:01.0376635'),
CAST('1900-01-01 00:00:00.0000000' as datetime2)
)
)
If you want to do averages, then the best approach is to convert to seconds or fractions of a day. Day fractions are convenient in SQL Server, because you can do things like:
select avg(cast(endtime - starttime) as float)
from t
You can convert it back to a datetime using the reverse cast:
select cast(avg(cast(endtime - starttime as float) as datetime)
from t
The arithmetic to get the times in the format you want . . . that is a pain. You might consider including days in the final format, and using:
select right(convert(varchar(255), <val>, 120), 10)
To get the hours exceeding 24, here is another approach:
select cast(floor(cast(<val> as float)*24) as varchar(255))+right(convert(varchar(255), <val>, 120), 6)
It uses convert for minutes and seconds, which should be padded with 0s on the left. It then appends the hours as a separate value.
Starting in SQL SERVER 2012, you don't need to use DATEDIFF function. You can use FORMAT function to achieve what you want:
SELECT
FORMAT(CONVERT(TIME, [appoitment].[Start] - [appointment].[End]), N'hh\:mm') AS 'Duration'
FROM
[tblAppointment] (NOLOCK)
A way that avoids overflows and can include days and go all the way to milliseconds in the output:
DECLARE #startDate AS DATETIME = '2018-06-01 14:20:02.100'
DECLARE #endDate AS DATETIME = '2018-06-02 15:23:09.000'
SELECT CAST(DATEDIFF(day,'1900-01-01', #endDate - #startDate) AS VARCHAR) + 'd ' + CONVERT(varchar(22), #endDate - #startDate, 114)
The above will return
1d 01:03:06:900
And, off course, you can use the formatting of your choice
SQL Supports datetime substraction which outputs a new datetime relative to the MIN date (for instance 1900-01-01, you can probably get this value from some system variable) This works better than DATEDIFF, because DATEDIFF will count ONE for each "datepart boundaries crossed", even if the elapsed time is less than a whole datapart. Another nice thing about this method is that it allows you to use the date formatting conversions.
If days is the (positive) number of days, like 0.5 for 12 hours, use this expression to format it as a proper duration:
CONVERT(varchar(9), FLOOR(days * 24)) + RIGHT(CONVERT(char(19), CAST(days AS datetime), 120), 6)
Excel will understands values up to 9999:59:59 when pasted. There apply a custom format: [h]:mm:ss in the English version ([u]:mm:ss for Dutch).