Reputation: 3690
Looking for the most efficient and elegant way to do truncate the time to the minute
-- I need to truncate the time to the minute,
-- this code almost works but rounds up
SELECT
CAST('2021-09-02T15:15:30.9233333' AS datetime2(7)) AS EventDatetime2,
CAST(CAST('2021-09-02T15:15:30.9233333' AS datetime2(7)) AS TIME(0)) AS EventTime
Upvotes: 2
Views: 830
Reputation: 725
Combining the DATEADD
and CAST(... AS SMALLDATETIME)
approaches effectively gives you a minute "floor", like so:
SELECT CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7)) AS EventDatetime2,
CAST(CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7)) AS TIME(0)) AS EventTime,
CAST(CAST(DATEADD(
SECOND,
(DATEPART(SECOND, CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7))) * -1),
CAST('2021-09-02T15:15:30.9233333' AS DATETIME2(7))) AS SMALLDATETIME) AS TIME(0));
EventDatetime2 | EventTime | (No column name) |
---|---|---|
2021-09-02 15:15:30.9233333 | 15:15:31 | 15:15:00 |
The DATEADD
in this example subtracts the number of seconds from the datetime before converting it to a smalldatetime, so when that cast/convert does its rounding it will always go to the lower minute.
If, however, your input value is the sort of string literal that the wording of your question implies, you could also do this:
SELECT CAST(SUBSTRING('2021-09-02T15:15:30.9233333', CHARINDEX('T', '2021-09-02T15:15:30.9233333')+1, 6) + '00' AS TIME(0));
and get this result:
15:15:00
Upvotes: 0
Reputation: 81930
Just another option using left()
and the implicit conversion.
Depending on the actual USE CASE, the outer convert()
is optional
Example
DECLARE @dt datetime2(7) = '2021-09-02T15:15:30.9233333';
select convert(smalldatetime,left(@dt,16))
Results
2021-09-02 15:15:00
Upvotes: 1
Reputation:
As Larnu posted, if you want to round up or down depending on the seconds value, a simple convert to smalldatetime will do.
If you want to truncate, there are several ways, the simplest is probably just to add minutes to midnight (only posting because I prefer without the magic dates like 1900-01-01):
DECLARE @dt datetime2(7) = '2021-09-02T15:15:30.9233333';
DECLARE @d datetime2(7) = CONVERT(date, @dt);
SELECT DATEADD(MINUTE, DATEDIFF(MINUTE, @d, @dt), @d);
Another way is more intuitive but a little ugly:
DECLARE @dt datetime2(7) = '2021-09-02T15:15:30.9233333';
SELECT SMALLDATETIMEFROMPARTS
(
DATEPART(YEAR, @dt),
DATEPART(MONTH, @dt),
DATEPART(DAY, @dt),
DATEPART(HOUR, @dt),
DATEPART(MINUTE, @dt)
);
Upvotes: 5
Reputation: 95564
If you want to "round" to the nearest minute you could just CONVERT
the value to a smalldatetime
; they are only accurate to 1 minute:
SELECT CONVERT(smalldatetime,CONVERT(datetime2,'2021-09-02T15:15:30.9233333'));
If you want to, you can then CONVERT
back to your original data type.
If you want to truncate (so strip the minutes) you could use the old DATEDIFF
and DATEADD
method:
DECLARE @DateTime2 datetime2(7) = '2021-09-02T15:15:30.9233333';
SELECT DATEADD(MINUTE,DATEDIFF(MINUTE,'19000101',@DateTime2),CONVERT(datetime2(7),'19000101'));
Upvotes: 2