SQL DATETIME Math - sql

I am trying to do the following:
Format GetDate() to display only the minutes
Format a varchar column to display only the minutes
Subtract the current time HH:MM:SS from GetDate() and the VarChar column
This is what I have
CONVERT(VARCHAR(5), GETDATE(), 108) - substring(convert(varchar(20), ColumnName, 9), 13, 5)
but I am getting this error and need some help please:
Operand data type varchar is invalid for subtract operator.

What you want is datepart(mi).
To get the minutes for getdate():
select datepart(mi, getdate())
To subtract a number of minutes from a datetime:
select dateadd(mi, - <minutes>, <datevalue>)
To remove the time from getdate(), just cast to date (in more recent versions of SQL Server):
select cast(getdate() as date)
To get the difference in minutes, use datediff:
select datediff(mi, <datestart>, <dateend>)
What are you really trying to accomplish?

I think this is what you want:
declare #str varchar(30)
set #str = '2012-08-14 10:12:02.690'
select datediff(minute, cast(#str as datetime), getdate())
Results when getdate() = '2012-08-14 11:21:10.250' is total minutes even over 60:
69

Related

SQL Column Concatenation whilst keeping the datatype of first column [duplicate]

In an extract I am dealing with, I have 2 datetime columns. One column stores the dates and another the times as shown.
How can I query the table to combine these two fields into 1 column of type datetime?
Dates
2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000
Times
1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
You can simply add the two.
if the Time part of your Date column is always zero
and the Date part of your Time column is also always zero (base date: January 1, 1900)
Adding them returns the correct result.
SELECT Combined = MyDate + MyTime FROM MyTable
Rationale (kudos to ErikE/dnolan)
It works like this due to the way the date is stored as two 4-byte
Integers with the left 4-bytes being the date and the right
4-bytes being the time. Its like doing $0001 0000 + $0000 0001 =
$0001 0001
Edit regarding new SQL Server 2008 types
Date and Time are types introduced in SQL Server 2008. If you insist on adding, you can use Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)
Edit2 regarding loss of precision in SQL Server 2008 and up (kudos to Martin Smith)
Have a look at How to combine date and time to datetime2 in SQL Server? to prevent loss of precision using SQL Server 2008 and up.
If the time element of your date column and the date element of your time column are both zero then Lieven's answer is what you need. If you can't guarantee that will always be the case then it becomes slightly more complicated:
SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table
This is an alternative solution without any char conversions:
DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))
You will only get milliseconds accuracy this way, but that would normally be OK. I have tested this in SQL Server 2008.
This worked for me
CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)
(on SQL 2008 R2)
If you're not using SQL Server 2008 (i.e. you only have a DateTime data type), you can use the following (admittedly rough and ready) TSQL to achieve what you want:
DECLARE #DateOnly AS datetime
DECLARE #TimeOnly AS datetime
SET #DateOnly = '07 aug 2009 00:00:00'
SET #TimeOnly = '01 jan 1899 10:11:23'
-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly))
-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
-- Concatenates Date and Time parts.
SELECT
CAST(
DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly)) + ' ' +
DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
as datetime)
It's rough and ready, but it works!
If both of your fields are datetime then simply adding those will work.
eg:
Declare #d datetime, #t datetime
set #d = '2009-03-12 00:00:00.000';
set #t = '1899-12-30 12:30:00.000';
select #d + #t
If you used Date & Time datatype then just cast the time to datetime
eg:
Declare #d date, #t time
set #d = '2009-03-12';
set #t = '12:30:00.000';
select #d + cast(#t as datetime)
This was my solution which ignores the date value of the time column
CAST(Tbl.date as DATETIME) + CAST(CAST(Tbl.TimeFrom AS TIME) as DATETIME)
Hope this helps others
Convert the first date stored in a datetime field to a string, then convert the time stored in a datetime field to string, append the two and convert back to a datetime field all using known conversion formats.
Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103)
Convert both field into DATETIME :
SELECT CAST(#DateField as DATETIME) + CAST(#TimeField AS DATETIME)
and if you're using Getdate() use this first:
DECLARE #FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(#FechaActual as DATETIME) + CAST(#HoraInicioTurno AS DATETIME)
I had many errors as stated above so I did it like this
try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime
It worked for me.
Finding this works for two dates where you want time from one and date from the other:
declare #Time as datetime = '2021-11-19 12:34'
declare #Date as datetime = '2021-10-10'
SELECT #time + datediff(day, #Time, #Date)
DECLARE #Dates table ([Date] datetime);
DECLARE #Times table ([Time] datetime);
INSERT INTO #Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-30 00:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
WITH Dates (ID, [Date])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM #Dates
), Times (ID, [Time])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM #Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
JOIN Times ON Times.ID = Dates.ID
Prints:
2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
To combine date from a datetime column and time from another datetime column this is the best fastest solution for you:
select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
SELECT CAST(CAST(#DateField As Date) As DateTime) + CAST(CAST(#TimeField As Time) As DateTime)
Another way is to use CONCATand CAST, be aware, that you need to use DATETIME2(x) to make it work. You can set x to anything between 0-7 7 meaning no precision loss.
DECLARE #date date = '2018-03-12'
DECLARE #time time = '07:00:00.0000000'
SELECT CAST(CONCAT(#date, ' ', #time) AS DATETIME2(7))
Returns 2018-03-12 07:00:00.0000000
Tested on SQL Server 14
simply concatenate both , but cast them first as below
select cast(concat(Cast(DateField as varchar), ' ', Cast(TimeField as varchar)) as datetime) as DateWithTime from TableName;
select s.SalesID from SalesTbl s
where cast(cast(s.SaleDate as date) as datetime) + cast(cast(s.SaleCreatedDate as time) as datetime) between #FromDate and #ToDate
The existing answers do not address the datetime2 datatype so I will add mine:
Assuming that you want to add a time value to a datetime2 value where:
The datetime2 value could contain non-zero time component and/or fractional seconds
The time value could contain the value 23:59:59.9999999 which is 86,399.9999999 seconds, 86,399,999,999.9 microseconds or 86,399,999,999,900 nanoseconds¹
Due to the limitations of dateadd function¹ you must add them in two steps:
Convert the time value to seconds and use dateadd(second, ...)
Extract the nanoseconds from the time value and use dateadd(nanosecond, ...) to add them to the date calculated above
declare #dv datetime2 = '2000-01-01 12:34:56.7890123';
declare #tv time = '23:59:59.9999999';
select dateadd(
nanosecond,
datepart(nanosecond, #tv),
dateadd(
second,
datepart(hour, #tv) * 60 * 60 + datepart(minute, #tv) * 60 + datepart(second, #tv),
#dv
)
);
-- 2000-01-02 12:34:56.7890122
¹ Nanosecond values might not fit in int datatype which dateadd function expects.
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table
Works like a charm
I ran into similar situation where I had to merge Date and Time fields to DateTime field. None of the above mentioned solution work, specially adding two fields as the data type for addition of these 2 fields is not same.
I created below solution, where I added hour and then minute part to the date. This worked beautifully for me. Please check it out and do let me know if you get into any issues.
;with tbl
as
(
select StatusTime = '12/30/1899 5:17:00 PM', StatusDate = '7/24/2019 12:00:00 AM'
)
select DATEADD(MI, DATEPART(MINUTE,CAST(tbl.StatusTime AS TIME)),DATEADD(HH, DATEPART(HOUR,CAST(tbl.StatusTime AS TIME)), CAST(tbl.StatusDate as DATETIME)))
from tbl
Result: 2019-07-24 17:17:00.000

Concatenate date and string to create datetime in SQL

I need to concatenate a datetime and a time field in SQL to a single date time.
e.g I have a datetime of 2017-09-05 00:00:00.000 and a string time of 11:00. What I want is a single field in a view of 2017-09-05 11:00:00.000
I have tried casting the datetime to a date and then concatenate the new date and string date field together but this doesn't work.
To cast the datetime I am using: CAST(dtDate AS DATE) AS dtNewDate which works fine. When I then use: CAST(dtNewDate + szTime AS datetime) AS dtNewDateTime the creation of the view works fine but selecting the top 1000 returns a "conversion failed when converting date and/or time from character string."
Is there an easier way to do this or can anyone offer some advise (other than storing the date and time in a single datetime field in the first place as it is populated by a third party application which I do not have access to change)
You can add two datetime values together, so try:
CAST(dtDate AS DATETIME) + CAST(CAST(szTime AS TIME) as DATETIME)
Assuming 11:00 stands for 11:00:00, you can do something like this:
SELECT dtDate + CONVERT(DateTime, szTime, 108)
FROM...
See a live demo on rextester
You can try following.
DECLARE #YourDate AS DATETIME
SET #YourDate = CONVERT(VARCHAR(10), '2017-09-05 00:00:00.000', 111) + ' 11:00'
PRINT #YourDate
another way is to get the hour from your stringfield, convert it to int, and add that as hours to the datetime
declare #date datetime = '20170905'
declare #stringtime varchar(5) = '11:00'
select left(#stringtime, 2),
dateadd(hour, convert(int, left(#stringtime, 2)), #date)
If you also need the minutes you can do it like this :
declare #date datetime = '20170905'
declare #stringtime varchar(5) = '11:05'
select left(#stringtime, 2),
right(#stringtime, 2),
dateadd(minute, convert(int, right(#stringtime, 2)), dateadd(hour, convert(int, left(#stringtime, 2)), #date))
This will only work if the stringfield is always in format hh:mm
If you care about precision with DATETIME2,
DECLARE #D DATETIME = '2017-01-01';
DECLARE #T varchar(7) = '11:00';
SELECT DATEADD(day, DATEDIFF(day, '19000101', #D), CAST(CAST(#T AS TIME) AS DATETIME2(7)));
Running example here

How do I convert time into an integer in SQL Server

I have a date column and a time column that are integers
I converted the date portion like this
select convert(int, convert(varchar(10), getdate(), 112))
I thought I could do the same with this query that gives the time in HH:mm:ss
SELECT CONVERT(VARCHAR(8), GETDATE(), 108)
How do I convert just the time into an integer?
This should convert your time into an integer representing seconds from midnight.
SELECT (DATEPART(hour, Col1) * 3600) + (DATEPART(minute, Col1) * 60) + DATEPART(second, Col1) as SecondsFromMidnight FROM T1;
Assuming you are looking for the "time" analogy to the "date" portion of your code which takes YYYYMMDD and turns it into an INT, you can:
start with the HH:mm:ss format given by the style number 108
remove the colons to get that string into HHmmss
then convert that to INT
For example:
SELECT REPLACE(
CONVERT(VARCHAR(8), GETDATE(), 108),
':',
''
) AS [StringVersion],
CONVERT(INT, REPLACE(
CONVERT(VARCHAR(8), GETDATE(), 108),
':',
''
)
) AS [IntVersion];
You can use the differece between midnight and the time of the day. For example, using getdate(), you can know the percentage of the time of the day with this query:
select convert(float,getdate()-convert(date,getdate()))
You can then convert this number to seconds
select convert(int,86400 * convert(float,getdate()-convert(date,getdate())))
You'll get the number of seconds from midnight
I think this is easier to understand when using with a SQL Update statement.
UPDATE dbo.MyTable
SET TIME_AS_INT = CAST(REPLACE(CAST(CONVERT(Time(0), GETDATE()) AS varchar),':','') AS INT)
To add/subtract time from the result before converting use dateadd()
SELECT CAST(REPLACE(CAST(CONVERT(Time(0), dateadd(MINUTE, 1, getdate())) AS varchar),':','') AS INT)

Converting datetime format to 12 hour

I have this query
select CONVERT(varchar(5), tdate ,108) AS [Time] from table
which gives me the time in 24 hour format( military)
I wanted to convert it into a 12 hour format so i tried the query below
select SUBSTRING(CONVERT(VARCHAR, tdate, 100),13,2) + ':'
+ SUBSTRING(CONVERT(VARCHAR, tdate, 100),16,2) + ''
+ SUBSTRING(CONVERT(VARCHAR, tdate, 100),18,2) AS T
from table
and i get the 12 hour format but I am just curious if there is a shorter or better way of doing it. any help?
If you want to convert the current datetime for example:
SELECT CONVERT(VARCHAR, getdate(), 100) AS DateTime_In_12h_Format
Instead of getdate() you can put your desired column in a query (such as tdate in your example). If you want JUST the time in 12h and not the date and time use substring/right to separate them. It seems that you already know how to =).
This page lists every datetime conversion. It's really handy if you need other types of conversions.
This will return just the time, not the date.
SELECT RIGHT(CONVERT(VARCHAR, getdate(), 100), 7) AS time
For your table data:
select RIGHT(CONVERT(varchar, tdate ,100), 7) AS [Time] from table
Below code will return only time like 10:30 PM
SELECT FORMAT(CAST(getdate() AS DATETIME),'hh:mm tt') AS [Time]
Get date of server
SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), GETDATE(), 100), 7))
or
If it is stored in the table
SELECT LTRIM(RIGHT(CONVERT(VARCHAR(20), datename, 100), 7))
Result:
11:41AM
ifnull(date_format(at.date_time,'%d/%m/%Y'),"") AS date_time,
ifnull(time_format(at.date_time ,'%h:%i:%s'),"") AS date_time
This is how a SQL procedure looks...(for separating date and time)..there is no need of a special column for time/date....
Note:if H instead of h it will show the "hour in 24 hour" format

How to combine date from one field with time from another field - MS SQL Server

In an extract I am dealing with, I have 2 datetime columns. One column stores the dates and another the times as shown.
How can I query the table to combine these two fields into 1 column of type datetime?
Dates
2009-03-12 00:00:00.000
2009-03-26 00:00:00.000
2009-03-26 00:00:00.000
Times
1899-12-30 12:30:00.000
1899-12-30 10:00:00.000
1899-12-30 10:00:00.000
You can simply add the two.
if the Time part of your Date column is always zero
and the Date part of your Time column is also always zero (base date: January 1, 1900)
Adding them returns the correct result.
SELECT Combined = MyDate + MyTime FROM MyTable
Rationale (kudos to ErikE/dnolan)
It works like this due to the way the date is stored as two 4-byte
Integers with the left 4-bytes being the date and the right
4-bytes being the time. Its like doing $0001 0000 + $0000 0001 =
$0001 0001
Edit regarding new SQL Server 2008 types
Date and Time are types introduced in SQL Server 2008. If you insist on adding, you can use Combined = CAST(MyDate AS DATETIME) + CAST(MyTime AS DATETIME)
Edit2 regarding loss of precision in SQL Server 2008 and up (kudos to Martin Smith)
Have a look at How to combine date and time to datetime2 in SQL Server? to prevent loss of precision using SQL Server 2008 and up.
If the time element of your date column and the date element of your time column are both zero then Lieven's answer is what you need. If you can't guarantee that will always be the case then it becomes slightly more complicated:
SELECT DATEADD(day, 0, DATEDIFF(day, 0, your_date_column)) +
DATEADD(day, 0 - DATEDIFF(day, 0, your_time_column), your_time_column)
FROM your_table
This is an alternative solution without any char conversions:
DATEADD(ms, DATEDIFF(ms, '00:00:00', [Time]), CONVERT(DATETIME, [Date]))
You will only get milliseconds accuracy this way, but that would normally be OK. I have tested this in SQL Server 2008.
This worked for me
CAST(Tbl.date as DATETIME) + CAST(Tbl.TimeFrom AS TIME)
(on SQL 2008 R2)
If you're not using SQL Server 2008 (i.e. you only have a DateTime data type), you can use the following (admittedly rough and ready) TSQL to achieve what you want:
DECLARE #DateOnly AS datetime
DECLARE #TimeOnly AS datetime
SET #DateOnly = '07 aug 2009 00:00:00'
SET #TimeOnly = '01 jan 1899 10:11:23'
-- Gives Date Only.
SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly))
-- Gives Time Only.
SELECT DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
-- Concatenates Date and Time parts.
SELECT
CAST(
DATEADD(dd, 0, DATEDIFF(dd, 0, #DateOnly)) + ' ' +
DATEADD(Day, -DATEDIFF(Day, 0, #TimeOnly), #TimeOnly)
as datetime)
It's rough and ready, but it works!
If both of your fields are datetime then simply adding those will work.
eg:
Declare #d datetime, #t datetime
set #d = '2009-03-12 00:00:00.000';
set #t = '1899-12-30 12:30:00.000';
select #d + #t
If you used Date & Time datatype then just cast the time to datetime
eg:
Declare #d date, #t time
set #d = '2009-03-12';
set #t = '12:30:00.000';
select #d + cast(#t as datetime)
This was my solution which ignores the date value of the time column
CAST(Tbl.date as DATETIME) + CAST(CAST(Tbl.TimeFrom AS TIME) as DATETIME)
Hope this helps others
Convert the first date stored in a datetime field to a string, then convert the time stored in a datetime field to string, append the two and convert back to a datetime field all using known conversion formats.
Convert(datetime, Convert(char(10), MYDATETIMEFIELD, 103) + ' ' + Convert(char(8), MYTIMEFIELD, 108), 103)
Convert both field into DATETIME :
SELECT CAST(#DateField as DATETIME) + CAST(#TimeField AS DATETIME)
and if you're using Getdate() use this first:
DECLARE #FechaActual DATETIME = CONVERT(DATE, GETDATE());
SELECT CAST(#FechaActual as DATETIME) + CAST(#HoraInicioTurno AS DATETIME)
I had many errors as stated above so I did it like this
try_parse(concat(convert(date,Arrival_date),' ',arrival_time) as datetime) AS ArrivalDateTime
It worked for me.
Finding this works for two dates where you want time from one and date from the other:
declare #Time as datetime = '2021-11-19 12:34'
declare #Date as datetime = '2021-10-10'
SELECT #time + datediff(day, #Time, #Date)
DECLARE #Dates table ([Date] datetime);
DECLARE #Times table ([Time] datetime);
INSERT INTO #Dates VALUES('2009-03-12 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-26 00:00:00.000');
INSERT INTO #Dates VALUES('2009-03-30 00:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 12:30:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
INSERT INTO #Times VALUES('1899-12-30 10:00:00.000');
WITH Dates (ID, [Date])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Date]), [Date] FROM #Dates
), Times (ID, [Time])
AS (
SELECT ROW_NUMBER() OVER (ORDER BY [Time]), [Time] FROM #Times
)
SELECT Dates.[Date] + Times.[Time] FROM Dates
JOIN Times ON Times.ID = Dates.ID
Prints:
2009-03-12 10:00:00.000
2009-03-26 10:00:00.000
2009-03-30 12:30:00.000
To combine date from a datetime column and time from another datetime column this is the best fastest solution for you:
select cast(cast(DateColumn as date) as datetime) + cast(TimeColumn as datetime) from YourTable
SELECT CAST(CAST(#DateField As Date) As DateTime) + CAST(CAST(#TimeField As Time) As DateTime)
Another way is to use CONCATand CAST, be aware, that you need to use DATETIME2(x) to make it work. You can set x to anything between 0-7 7 meaning no precision loss.
DECLARE #date date = '2018-03-12'
DECLARE #time time = '07:00:00.0000000'
SELECT CAST(CONCAT(#date, ' ', #time) AS DATETIME2(7))
Returns 2018-03-12 07:00:00.0000000
Tested on SQL Server 14
simply concatenate both , but cast them first as below
select cast(concat(Cast(DateField as varchar), ' ', Cast(TimeField as varchar)) as datetime) as DateWithTime from TableName;
select s.SalesID from SalesTbl s
where cast(cast(s.SaleDate as date) as datetime) + cast(cast(s.SaleCreatedDate as time) as datetime) between #FromDate and #ToDate
The existing answers do not address the datetime2 datatype so I will add mine:
Assuming that you want to add a time value to a datetime2 value where:
The datetime2 value could contain non-zero time component and/or fractional seconds
The time value could contain the value 23:59:59.9999999 which is 86,399.9999999 seconds, 86,399,999,999.9 microseconds or 86,399,999,999,900 nanoseconds¹
Due to the limitations of dateadd function¹ you must add them in two steps:
Convert the time value to seconds and use dateadd(second, ...)
Extract the nanoseconds from the time value and use dateadd(nanosecond, ...) to add them to the date calculated above
declare #dv datetime2 = '2000-01-01 12:34:56.7890123';
declare #tv time = '23:59:59.9999999';
select dateadd(
nanosecond,
datepart(nanosecond, #tv),
dateadd(
second,
datepart(hour, #tv) * 60 * 60 + datepart(minute, #tv) * 60 + datepart(second, #tv),
#dv
)
);
-- 2000-01-02 12:34:56.7890122
¹ Nanosecond values might not fit in int datatype which dateadd function expects.
SELECT CAST(your_date_column AS date) + CAST(your_time_column AS datetime) FROM your_table
Works like a charm
I ran into similar situation where I had to merge Date and Time fields to DateTime field. None of the above mentioned solution work, specially adding two fields as the data type for addition of these 2 fields is not same.
I created below solution, where I added hour and then minute part to the date. This worked beautifully for me. Please check it out and do let me know if you get into any issues.
;with tbl
as
(
select StatusTime = '12/30/1899 5:17:00 PM', StatusDate = '7/24/2019 12:00:00 AM'
)
select DATEADD(MI, DATEPART(MINUTE,CAST(tbl.StatusTime AS TIME)),DATEADD(HH, DATEPART(HOUR,CAST(tbl.StatusTime AS TIME)), CAST(tbl.StatusDate as DATETIME)))
from tbl
Result: 2019-07-24 17:17:00.000