how to enter manual time stamp in get date () - sql

how to enter manual time stamp in get date () ?
select conver(varchar(10),getdate(),120)
returns 2010-06-07
now i want to enter my own time stamp in this like
2010-06-07 10.00.00.000
i m using this in
select * from sample table where time_stamp ='2010-06-07 10.00.00.000'
since i m trying to automate this query i need the current date but i need different time stamp can it be done .

You just want to append a time to your result? Like this?
select convert(varchar(10),getdate(),120) + ' 10.00.00.000'
or if you want to get it back to a DATETIME type:
select convert(datetime,convert(varchar(10),getdate(),120) + ' 10:00')

--SQL Server 2008
DECLARE #MyTime time, #MyDate date
SELECT #MyDate = GETDATE(), #MyTime = '10:00:00'
SELECT CAST(#MyDate AS datetime) + #MyTime
--SQL Server 2005 and before
DECLARE #MyTime datetime, #MyDate datetime
SELECT
#MyDate = DATEADD(day, 0, DATEDIFF(day, 0, GETDATE())),
#MyTime = '19000101 10:00:00'
SELECT #MyDate + #MyTime
"zero" date = 01 Jan 1900 in SQL Server

SELECT DATEADD(hh, 1, FLOOR(CAST(GETDATE() AS FLOAT)))
Once you have the floor of the date, you can add time to it.
DATEADD(datepart, number, date)

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

Why does my code execute IF block even if dates comparison fail?

Expiry Date = '2017-10-16' and ExpiryTime='12:00pm' in table and in our country Getdate is '2017-10-16' and currentdatetime is '2017-10-16 11:05:33.503'
but still, my code executes the IF condition which it should not. Why ?
Declare #ExpiryDate date
Declare #ExpiryTime varchar(10)
Set #ExpiryDate= (Select convert(varchar(11), ExpiryDate, 106) from Works where NIT_No= #NITNo and WorkNo= #WorkNo)
Set #ExpiryTime= (Select CAST(ExpiryTime as TIME(0)) from Works where NIT_No= #NITNo and WorkNo= #WorkNo)
IF(CONVERT(DATETIME,CONVERT(VARCHAR,#ExpiryDate,106)+ ' ' + #ExpiryTime) <= CONVERT(datetime, GETDATE()))
Begin
RAISERROR('Sorry, Expiry date and time has passed', 16, 10);
return;
End
12:00pm is translated to 00:00 in 24 hour format. If you combine the current date and 12:00pm, you expect the result to be midnight of the next day, but actually you get midnight of the current day.
That should work:
Declare #ExpiryDate date
Declare #ExpiryTime varchar(10)
Set #ExpiryDate= (Select convert(varchar(11), ExpiryDate, 106) from Works where NIT_No= #NITNo and WorkNo= #WorkNo)
Set #ExpiryTime= (Select CAST(ExpiryTime as TIME(0)) from Works where NIT_No= #NITNo and WorkNo= #WorkNo)
declare #dateTimeCombined datetime = dateadd(ms, datediff(ms, '00:00:00', #ExpiryTime), cast(#ExpiryDate as datetime))
IF #dateTimeCombined <= CONVERT(datetime, GETDATE())
Begin
RAISERROR('Sorry, Expiry date and time has passed', 16, 10);
return;
End

How to get last date of month SQL Server 2008

I created a function "ufngetFirstDateOfMonth" and "ufngetLastDateOfMonth" stored in Microsoft SQL Server 2008. My purpose is to send some date into the function and it will return the first date of month with '00:00:00' or the last date of month with '23:59:59'.
I call the function like this:
exec ufngetLastDateOfMonth('2014-10-15')
and normally it returns '2014-10-31 23:59:59'
but when I send the last date of months that have 31 days (august, january,...):
exec ufngetLastDateOfMonth('2014-10-31')
it return '2014-10-30 23:59:59' whick is not correct Actally, it should be '2014-10-31 23:59:59'
Something goes wrong here...
This is my function:
CREATE FUNCTION [dbo].[ufnLastDateOfMonth](#Date date)
RETURNS varchar(50)
AS
BEGIN
DECLARE #New_Date varchar(50)
select #New_date = cast(dateadd(dd,-(DAY(#Date )),DATEADD(mm,1,#Date ))as varchar(50)) + ' 23:59:59'
RETURN #New_Date
END
To get the last day you can do this:
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,'2014-08-12')+1,0))
Adding to your function:
select #New_date = DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#date)+1,0))
Source:
SQL SERVER – Find Last Day of Any Month – Current Previous Next
For those who are using SQL Server 2012,
EOMONTH function could be an alternative.
DECLARE #date DATETIME = '12/1/2011';
SELECT EOMONTH ( #date ) AS Result;
GO
Source: https://msdn.microsoft.com/en-us/library/hh213020.aspx
Go to the first day of the month. Add one month. Then subtract one day. Or, in your case, one second:
select #New_date = dateadd(second, -1, dateadd(month, 1, dateadd(day, -(DAY(#Date) + 1)) ) )
You should use convert() if you want this as a string. I would instead suggest that the function return a datetime.
Use this
DECLARE #curdate datetime;
SET #curdate = GETDATE(); -- you can pass your date here
--SET #curdate = '2014-10-15'; Example
SELECT DATEADD(MONTH,1+DATEDIFF(MONTH,0,#curdate),-1);
OR
SELECT DATEADD(MONTH,1+DATEDIFF(MONTH,0,GETDATE()),-1);
you can try this
select DATEADD(d, -1, DATEADD(m, DATEDIFF(m, 0, GETDATE()) + 1, 0)) As EndDateOfCurrentMonth
or this
select DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) As StartDateOfCurrentMonth
Just try this:
SELECT EOMONTH('2000/2/1') Last_Date
Note: EOMONTH function is available in SQL Server version >= 2012

Convert Datetime column from UTC to local time in select statement

I'm doing a few SQL select queries and would like to convert my UTC datetime column into local time to be displayed as local time in my query results. Note, I am NOT looking to do this conversion via code but rather when I am doing manual and random SQL queries against my databases.
You can do this as follows on SQL Server 2008 or greater:
SELECT CONVERT(datetime,
SWITCHOFFSET(CONVERT(datetimeoffset,
MyTable.UtcColumn),
DATENAME(TzOffset, SYSDATETIMEOFFSET())))
AS ColumnInLocalTime
FROM MyTable
You can also do the less verbose:
SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), MyTable.UtcColumn)
AS ColumnInLocalTime
FROM MyTable
Whatever you do, do not use - to subtract dates, because the operation is not atomic, and you will on occasion get indeterminate results due to race conditions between the system datetime and the local datetime being checked at different times (i.e., non-atomically).
Please note that this answer does not take DST into account. If you want to include a DST adjustment, please also see the following SO question:
How to create Daylight Savings time Start and End function in SQL Server
I didn't find any of these example helpful in getting a datetime stored as UTC to a datetime in a specified timezone (NOT the timezone of the server because Azure SQL databases run as UTC). This is how I handled it. It's not elegant but it's simple and gives you the right answer without maintaining other tables:
select CONVERT(datetime, SWITCHOFFSET(dateTimeField, DATEPART(TZOFFSET,
dateTimeField AT TIME ZONE 'Eastern Standard Time')))
If your local date time is say Eastern Standard Time and you want to convert from UTC to that, then in Azure SQL and SQL Server 2016 and above, you can do:
SELECT YourUtcColumn AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time' AS
LocalTime
FROM YourTable
The full list of timezone names can be found with:
SELECT * FROM sys.time_zone_info
And yes, the timezones are badly named - even though it is Eastern Standard Time, daylight savings is taken into account.
If you need a conversion other than your server's location, here is a function that allows you to pass a standard offset and accounts for US Daylight Savings Times:
-- =============================================
-- Author: Ron Smith
-- Create date: 2013-10-23
-- Description: Converts UTC to DST
-- based on passed Standard offset
-- =============================================
CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
#UTC datetime,
#StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare
#DST datetime,
#SSM datetime, -- Second Sunday in March
#FSN datetime -- First Sunday in November
-- get DST Range
set #SSM = datename(year,#UTC) + '0314'
set #SSM = dateadd(hour,2,dateadd(day,datepart(dw,#SSM)*-1+1,#SSM))
set #FSN = datename(year,#UTC) + '1107'
set #FSN = dateadd(second,-1,dateadd(hour,2,dateadd(day,datepart(dw,#FSN)*-1+1,#FSN)))
-- add an hour to #StandardOffset if #UTC is in DST range
if #UTC between #SSM and #FSN
set #StandardOffset = #StandardOffset + 1
-- convert to DST
set #DST = dateadd(hour,#StandardOffset,#UTC)
-- return converted datetime
return #DST
END
GO
Using new SQL Server 2016 opportunities:
CREATE FUNCTION ToLocalTime(#dtUtc datetime, #timezoneId nvarchar(256))
RETURNS datetime
AS BEGIN
return #dtUtc AT TIME ZONE 'UTC' AT TIME ZONE #timezoneId
/* -- second way, faster
return SWITCHOFFSET(#dtUtc , DATENAME(tz, #dtUtc AT TIME ZONE #timezoneId))
*/
/* -- third way
declare #dtLocal datetimeoffset
set #dtLocal = #dtUtc AT TIME ZONE #timezoneId
return dateadd(minute, DATEPART (TZoffset, #dtLocal), #dtUtc)
*/
END
GO
But clr procedure works in 5 times faster :'-(
Pay attention that Offset for one TimeZone can change to winter or summer time. For example
select cast('2017-02-08 09:00:00.000' as datetime) AT TIME ZONE 'Eastern Standard Time'
select cast('2017-08-08 09:00:00.000' as datetime) AT TIME ZONE 'Eastern Standard Time'
results:
2017-02-08 09:00:00.000 -05:00
2017-08-08 09:00:00.000 -04:00
You can't just add constant offset.
If enabling CLR on your database is an option as well as using the sql server's timezone, it can be written in .Net quite easily.
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlDateTime fn_GetLocalFromUTC(SqlDateTime UTC)
{
if (UTC.IsNull)
return UTC;
return new SqlDateTime(UTC.Value.ToLocalTime());
}
}
A UTC datetime value goes in and the local datetime value relative to the server comes out. Null values return null.
None of these worked for me but this below worked 100%. Hope this can help others trying to convert it like I was.
CREATE FUNCTION [dbo].[fn_UTC_to_EST]
(
#UTC datetime,
#StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare
#DST datetime,
#SSM datetime, -- Second Sunday in March
#FSN datetime -- First Sunday in November
-- get DST Range
set #SSM = DATEADD(dd,7 + (6-(DATEDIFF(dd,0,DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 2,0))%7)),DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 2,0))+'02:00:00'
set #FSN = DATEADD(dd, (6-(DATEDIFF(dd,0,DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 10,0))%7)),DATEADD(mm,(YEAR(GETDATE())-1900) * 12 + 10,0)) +'02:00:00'
-- add an hour to #StandardOffset if #UTC is in DST range
if #UTC between #SSM and #FSN
set #StandardOffset = #StandardOffset + 1
-- convert to DST
set #DST = dateadd(hour,#StandardOffset,#UTC)
-- return converted datetime
return #DST
END
Well if you store the data as UTC date in the database you can do something as simple as
select
[MyUtcDate] + getdate() - getutcdate()
from [dbo].[mytable]
this was it's always local from the point of the server and you are not fumbling with AT TIME ZONE 'your time zone name',
if your database get moved to another time zone like a client installation a hard coded time zone might bite you.
There is no simple way to do this in a correct AND generic way.
First of all it must be understood that the offset depends on the date in question, the Time Zone AND DST.
GetDate()-GetUTCDate only gives you the offset today at the server's TZ, which is not relevant.
I have seen only two working solution and I have search a lot.
1) A custom SQL function with a a couple of tables of base data such as Time Zones and DST rules per TZ.
Working but not very elegant. I can't post it since I don't own the code.
EDIT: Here is an example of this method
https://gist.github.com/drumsta/16b79cee6bc195cd89c8
2) Add a .net assembly to the db, .Net can do this very easily. This is working very well but the downside is that you need to configure several parameters on server level and the config is easily broken e.g. if you restore the database.
I use this method but I cant post it since I don't own the code.
This function will convert a UTC time to EST time with DST adjustment. You can change your designed time zone name in this function, or get it from registry:
Create Function fnConvertUTCTimetoESTTime(
#UTCTime as datetime
)
returns datetime
as
begin
return convert(datetime, convert(varchar(23), #UTCTime AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time', 121), 121)
end
go
select dbo.fnConvertUTCTimetoESTTime ('2020-3-8 5:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-3-8 6:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-3-8 7:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-3-8 8:00:00.000')
--returns 0:00am, 1:00am, 3:00am, 4:00am
select dbo.fnConvertUTCTimetoESTTime ('2020-11-1 4:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-11-1 5:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-11-1 6:00:00.000')
, dbo.fnConvertUTCTimetoESTTime ('2020-11-1 7:00:00.000')
--returns 0:00am, 1:00am, 1:00am, 2:00am
Note you can not just return "#UTCTime AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time'" as the result because this result is actually a UTC time in EST format (when you compare this "fake" EST time or include it in an order clause it will be converted back to a UTC time).
The easiest answer is not always at the bottom, but this time it is, and can be seen already somewhere hidden in above comments.
Take your own 'AT TIME ZONE' to capture the TzOffset for your column/data field, and not the current SYSDATETIME.
In below data, 2 queries, one on feb data (DST is off, winter in Amsterdam) +1 diff
and 2nd query on april data in Amsterdam, so +2 hour diff.
select top 2 month(receiveTimeUTC) as MonthInWinterOrSpring
, receiveTimeUTC
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, SYSDATETIMEOFFSET()))) as LocalTimeWrongNoDST
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, receiveTimeUTC AT TIME ZONE 'Central European Standard Time' ))) as LocalTimeWithDST
from sensordetails order by id
select top 2 month(receiveTimeUTC) as MonthInWinterOrSpring, receiveTimeUTC
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, SYSDATETIMEOFFSET()))) as LocalTimeWrongNoDST
, CONVERT(datetime, SWITCHOFFSET(CONVERT(datetimeoffset, receiveTimeUTC), DATENAME(TzOffset, receiveTimeUTC AT TIME ZONE 'Central European Standard Time' ))) as LocalTimeWithDST
from sensordetails order by id desc
Results:
So this is a T-SQL (SQL Server Answer), no need for storedproc of functions.
For Azure SQL and ##Version >= SQL Server 2016 users, Below is a simple function using AT TIME ZONE.
CREATE FUNCTION [dbo].[Global_Convert_UTCTimeTo_LocalTime]
(
#LocalTimeZone VARCHAR(50),
#UTCDateTime DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE #ConvertedDateTime DATETIME;
SELECT #ConvertedDateTime = #UTCDateTime AT TIME ZONE 'UTC' AT TIME ZONE #LocalTimeZone
RETURN #ConvertedDateTime
END
GO
For types of values that #LocalTimeZone can take, please go to this link or Go to KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
Here's a version that accounts for daylight savings, UTC offset, and is not locked into a particular year.
---------------------------------------------------------------------------------------------------
--Name: udfToLocalTime.sql
--Purpose: To convert UTC to local US time accounting for DST
--Author: Patrick Slesicki
--Date: 3/25/2014
--Notes: Works on SQL Server 2008R2 and later, maybe SQL Server 2008 as well.
-- Good only for US States observing the Energy Policy Act of 2005.
-- Function doesn't apply for years prior to 2007.
-- Function assumes that the 1st day of the week is Sunday.
--Tests:
-- SELECT dbo.udfToLocalTime('2014-03-09 9:00', DEFAULT)
-- SELECT dbo.udfToLocalTime('2014-03-09 10:00', DEFAULT)
-- SELECT dbo.udfToLocalTime('2014-11-02 8:00', DEFAULT)
-- SELECT dbo.udfToLocalTime('2014-11-02 9:00', DEFAULT)
---------------------------------------------------------------------------------------------------
ALTER FUNCTION udfToLocalTime
(
#UtcDateTime AS DATETIME
,#UtcOffset AS INT = -8 --PST
)
RETURNS DATETIME
AS
BEGIN
DECLARE
#PstDateTime AS DATETIME
,#Year AS CHAR(4)
,#DstStart AS DATETIME
,#DstEnd AS DATETIME
,#Mar1 AS DATETIME
,#Nov1 AS DATETIME
,#MarTime AS TIME
,#NovTime AS TIME
,#Mar1Day AS INT
,#Nov1Day AS INT
,#MarDiff AS INT
,#NovDiff AS INT
SELECT
#Year = YEAR(#UtcDateTime)
,#MarTime = CONVERT(TIME, DATEADD(HOUR, -#UtcOffset, '1900-01-01 02:00'))
,#NovTime = CONVERT(TIME, DATEADD(HOUR, -#UtcOffset - 1, '1900-01-01 02:00'))
,#Mar1 = CONVERT(CHAR(16), #Year + '-03-01 ' + CONVERT(CHAR(5), #MarTime), 126)
,#Nov1 = CONVERT(CHAR(16), #Year + '-11-01 ' + CONVERT(CHAR(5), #NovTime), 126)
,#Mar1Day = DATEPART(WEEKDAY, #Mar1)
,#Nov1Day = DATEPART(WEEKDAY, #Nov1)
--Get number of days between Mar 1 and DST start date
IF #Mar1Day = 1 SET #MarDiff = 7
ELSE SET #MarDiff = 15 - #Mar1Day
--Get number of days between Nov 1 and DST end date
IF #Nov1Day = 1 SET #NovDiff = 0
ELSE SET #NovDiff = 8 - #Nov1Day
--Get DST start and end dates
SELECT
#DstStart = DATEADD(DAY, #MarDiff, #Mar1)
,#DstEnd = DATEADD(DAY, #NovDiff, #Nov1)
--Change UTC offset if #UtcDateTime is in DST Range
IF #UtcDateTime >= #DstStart AND #UtcDateTime < #DstEnd SET #UtcOffset = #UtcOffset + 1
--Get Conversion
SET #PstDateTime = DATEADD(HOUR, #UtcOffset, #UtcDateTime)
RETURN #PstDateTime
END
GO
I found the one off function way to be too slow when there is a lot of data. So I did it through joining to a table function that would allow for a calculation of the hour diff. It is basically datetime segments with the hour offset. A year would be 4 rows. So the table function
dbo.fn_getTimeZoneOffsets('3/1/2007 7:00am', '11/5/2007 9:00am', 'EPT')
would return this table:
startTime endTime offset isHr2
3/1/07 7:00 3/11/07 6:59 -5 0
3/11/07 7:00 11/4/07 6:59 -4 0
11/4/07 7:00 11/4/07 7:59 -5 1
11/4/07 8:00 11/5/07 9:00 -5 0
It does account for daylight savings. A sample of how it is uses is below and the full blog post is here.
select mt.startTime as startUTC,
dateadd(hh, tzStart.offset, mt.startTime) as startLocal,
tzStart.isHr2
from MyTable mt
inner join dbo.fn_getTimeZoneOffsets(#startViewUTC, #endViewUTC, #timeZone) tzStart
on mt.startTime between tzStart.startTime and tzStart.endTime
declare #mydate2 datetime
set #mydate2=Getdate()
select #mydate2 as mydate,
dateadd(minute, datediff(minute,getdate(),#mydate2),getutcdate())
In postgres this works very nicely..Tell the server the time at which the time is saved, 'utc', and then ask it to convert to a specific timezone, in this case 'Brazil/East'
quiz_step_progresses.created_at at time zone 'utc' at time zone 'Brazil/East'
Get a complete list of timezones with the following select;
select * from pg_timezone_names;
See details here.
https://popsql.com/learn-sql/postgresql/how-to-convert-utc-to-local-time-zone-in-postgresql
Ron's answer contains an error. It uses 2:00 AM local time where the UTC equivalent is required. I don't have enough reputation points to comment on Ron's answer so a corrected version appears below:
-- =============================================
-- Author: Ron Smith
-- Create date: 2013-10-23
-- Description: Converts UTC to DST
-- based on passed Standard offset
-- =============================================
CREATE FUNCTION [dbo].[fn_UTC_to_DST]
(
#UTC datetime,
#StandardOffset int
)
RETURNS datetime
AS
BEGIN
declare
#DST datetime,
#SSM datetime, -- Second Sunday in March
#FSN datetime -- First Sunday in November
-- get DST Range
set #SSM = datename(year,#UTC) + '0314'
set #SSM = dateadd(hour,2 - #StandardOffset,dateadd(day,datepart(dw,#SSM)*-1+1,#SSM))
set #FSN = datename(year,#UTC) + '1107'
set #FSN = dateadd(second,-1,dateadd(hour,2 - (#StandardOffset + 1),dateadd(day,datepart(dw,#FSN)*-1+1,#FSN)))
-- add an hour to #StandardOffset if #UTC is in DST range
if #UTC between #SSM and #FSN
set #StandardOffset = #StandardOffset + 1
-- convert to DST
set #DST = dateadd(hour,#StandardOffset,#UTC)
-- return converted datetime
return #DST
END
The UNIX timestamp is merely the number of seconds between a particular date and the Unix Epoch,
SELECT DATEDIFF(SECOND,{d '1970-01-01'},GETDATE()) // This Will Return the UNIX timestamp In SQL server
you can create a function for local date time to Unix UTC conversion using Country Offset
Function to Unix Time Stamp In SQL server
It's simple. Try this for Azure SQL Server:
SELECT YourDateTimeColumn AT TIME ZONE 'Eastern Standard Time' FROM YourTable
For Local SQL Server :
SELECT CONVERT(datetime2, SWITCHOFFSET(CONVERT(datetimeoffset, gETDATE()), DATENAME(TzOffset, gETDATE() AT TIME ZONE 'Eastern Standard Time'))) FROM YourTable
For anyone still trying to solve this issue, here's a proof of concept that works in SQL Server 2017
declare
#StartDate date = '2020-01-01'
;with cte_utc as
(
select
1 as i
,CONVERT(datetime, #StartDate) AS UTC
,datepart(weekday, CONVERT(datetime, #StartDate)) as Weekday
,datepart(month, CONVERT(datetime, #StartDate)) as [Month]
,datepart(YEAR, CONVERT(datetime, #StartDate)) as [Year]
union all
Select
i + 1
,dateadd(d, 1, utc)
,datepart(weekday, CONVERT(datetime, dateadd(d, 1, utc))) as Weekday
,datepart(month, CONVERT(datetime, dateadd(d, 1, utc))) as [Month]
,datepart(YEAR, CONVERT(datetime, dateadd(d, 1, utc))) as [Year]
from
cte_utc
where
(i + 1) < 32767
), cte_utc_dates as
(
select
*,
DENSE_RANK()OVER(PARTITION BY [Year], [Month], [Weekday] ORDER BY Utc) WeekDayIndex
from
cte_utc
), cte_hours as (
select 0 as [Hour]
union all
select [Hour] + 1 from cte_hours where [Hour] < 23
)
select
d.*
, DATEADD(hour, h.Hour, d.UTC) AS UtcTime
,CONVERT(datetime, DATEADD(hour, h.Hour, d.UTC) AT TIME ZONE 'UTC' AT TIME ZONE 'Central Standard Time') CST
,CONVERT(datetime, DATEADD(hour, h.Hour, d.UTC) AT TIME ZONE 'UTC' AT TIME ZONE 'Eastern Standard Time') EST
from
cte_utc_dates d, cte_hours h
where
([Month] = 3 and [Weekday] = 1 and WeekDayIndex = 2 )-- dst start
or
([Month] = 11 and [Weekday] = 1 and WeekDayIndex = 1 )-- dst end
order by
utc
OPTION (MAXRECURSION 32767)
GO
As a warning - if you're going to use the following (note the milliseconds instead of minutes):
SELECT DATEADD(ms, DATEDIFF(ms, GETUTCDATE(), GETDATE()), MyTable.UtcColumn)
AS ColumnInLocalTime
FROM MyTable
Keep in mind that the DATEDIFF part will not always return the same number. So don't use it to compare DateTimes down to milliseconds.
This should be able to get server time with DST
declare #dt datetime
set #dt = getutcdate() -- GMT equivalent
sysdatetimeoffset takes DST into account
select [InputTime] = #dt
, [LocalTime2] = dateadd(mi, datediff(mi, sysdatetimeoffset(),getdate()), #dt)
First function: configured for italian time zone (+1, +2), switch dates: last sunday of march and october, return the difference between the current time zone and the datetime as parameter.
Returns:
current timezone < parameter timezone ==> +1
current timezone > parameter timezone ==> -1
else 0
The code is:
CREATE FUNCTION [dbo].[UF_ADJUST_OFFSET]
(
#dt_utc datetime2(7)
)
RETURNS INT
AS
BEGIN
declare #month int,
#year int,
#current_offset int,
#offset_since int,
#offset int,
#yearmonth varchar(8),
#changeoffsetdate datetime2(7)
declare #lastweek table(giorno datetime2(7))
select #current_offset = DATEDIFF(hh, GETUTCDATE(), GETDATE())
select #month = datepart(month, #dt_utc)
if #month < 3 or #month > 10 Begin Set #offset_since = 1 Goto JMP End
if #month > 3 and #month < 10 Begin Set #offset_since = 2 Goto JMP End
--If i'm here is march or october
select #year = datepart(yyyy, #dt_utc)
if #month = 3
Begin
Set #yearmonth = cast(#year as varchar) + '-03-'
Insert Into #lastweek Values(#yearmonth + '31 03:00:00.000000'),(#yearmonth + '30 03:00:00.000000'),(#yearmonth + '29 03:00:00.000000'),(#yearmonth + '28 03:00:00.000000'),
(#yearmonth + '27 03:00:00.000000'),(#yearmonth + '26 03:00:00.000000'),(#yearmonth + '25 03:00:00.000000')
--Last week of march
Select #changeoffsetdate = giorno From #lastweek Where datepart(weekday, giorno) = 1
if #dt_utc < #changeoffsetdate
Begin
Set #offset_since = 1
End Else Begin
Set #offset_since = 2
End
End
if #month = 10
Begin
Set #yearmonth = cast(#year as varchar) + '-10-'
Insert Into #lastweek Values(#yearmonth + '31 03:00:00.000000'),(#yearmonth + '30 03:00:00.000000'),(#yearmonth + '29 03:00:00.000000'),(#yearmonth + '28 03:00:00.000000'),
(#yearmonth + '27 03:00:00.000000'),(#yearmonth + '26 03:00:00.000000'),(#yearmonth + '25 03:00:00.000000')
--Last week of october
Select #changeoffsetdate = giorno From #lastweek Where datepart(weekday, giorno) = 1
if #dt_utc > #changeoffsetdate
Begin
Set #offset_since = 1
End Else Begin
Set #offset_since = 2
End
End
JMP:
if #current_offset < #offset_since Begin
Set #offset = 1
End Else if #current_offset > #offset_since Set #offset = -1 Else Set #offset = 0
Return #offset
END
Then the function that convert date
CREATE FUNCTION [dbo].[UF_CONVERT]
(
#dt_utc datetime2(7)
)
RETURNS datetime
AS
BEGIN
declare #offset int
Select #offset = dbo.UF_ADJUST_OFFSET(#dt_utc)
if #dt_utc >= '9999-12-31 22:59:59.9999999'
set #dt_utc = '9999-12-31 23:59:59.9999999'
Else
set #dt_utc = (SELECT DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), GETDATE()), #dt_utc) )
if #offset <> 0
Set #dt_utc = dateadd(hh, #offset, #dt_utc)
RETURN #dt_utc
END
-- get indian standard time from utc
CREATE FUNCTION dbo.getISTTime
(
#UTCDate datetime
)
RETURNS datetime
AS
BEGIN
RETURN dateadd(minute,330,#UTCDate)
END
GO
You have to reformat the string as well as converting to the correct time. In this case I needed Zulu time.
Declare #Date datetime;
Declare #DateString varchar(50);
set #Date = GETDATE();
declare #ZuluTime datetime;
Declare #DateFrom varchar (50);
Declare #DateTo varchar (50);
set #ZuluTime = DATEADD(second, DATEDIFF(second, GETDATE(), GETUTCDATE()), #Date);
set #DateString = FORMAT(#ZuluTime, 'yyyy-MM-ddThh:mm:ssZ', 'en-US' )
select #DateString;
Best way for Oracle:
With hardcoded datetime:
SELECT TO_CHAR(CAST((FROM_TZ(CAST(TO_DATE('2018-10-27 21:00', 'YYYY-MM-DD HH24:MI') AS TIMESTAMP), 'UTC') AT TIME ZONE 'EET') AS DATE), 'YYYY-MM-DD HH24:MI') UTC_TO_EET FROM DUAL
Result:
2018-10-28 00:00
With column and table names:
SELECT TO_CHAR(CAST((FROM_TZ(CAST(COLUMN_NAME AS TIMESTAMP), 'UTC') AT TIME ZONE 'EET') AS DATE), 'YYYY-MM-DD HH24:MI') UTC_TO_EET FROM TABLE_NAME
I have code to perform UTC to Local and Local to UTC times which allows conversion using code like this
DECLARE #usersTimezone VARCHAR(32)='Europe/London'
DECLARE #utcDT DATETIME=GetUTCDate()
DECLARE #userDT DATETIME=[dbo].[funcUTCtoLocal](#utcDT, #usersTimezone)
and
DECLARE #usersTimezone VARCHAR(32)='Europe/London'
DECLARE #userDT DATETIME=GetDate()
DECLARE #utcDT DATETIME=[dbo].[funcLocaltoUTC](#userDT, #usersTimezone)
The functions can support all or a subset of timezones in the IANA/TZDB as provided by NodaTime - see the full list at https://nodatime.org/TimeZones
Be aware that my use case means I only need a 'current' window, allowing the conversion of times within the range of about +/- 5 years from now. This means that the method I've used probably isn't suitable for you if you need a very wide period of time, due to the way it generates code for each timezone interval in a given date range.
The project is on GitHub: https://github.com/elliveny/SQLServerTimeConversion
This generates SQL function code as per this example
I used switchoffset to convert from utc time to local time. The time zone offset can be determined by using datename(tzoffset,systemdatetimeoffset()). Likewise if you want to get the elapsed time then use getutcdate keeping the time in utc time for the datediff function.
select
,[Field1]
,Format(SWITCHOFFSET([MyDateOnUTC],DATENAME(TZOFFSET, SYSDATETIMEOFFSET())),'MM/dd/yyyy hh:mm:ss tt') UtcToLocalTime
,datediff(minute,[ClaimedOnUTC],getutcdate()) ElapsedMinutes
from dbo.my_table
Here's a simpler one that takes dst in to account
CREATE FUNCTION [dbo].[UtcToLocal]
(
#p_utcDatetime DATETIME
)
RETURNS DATETIME
AS
BEGIN
RETURN DATEADD(MINUTE, DATEDIFF(MINUTE, GETUTCDATE(), #p_utcDatetime), GETDATE())
END
I've found that this function is faster than other solutions using a separate table or loops. It's just a basic case statement. Given that all months between April and October have a -4-hour offset (Eastern Time) we just need to add a few more case lines for the fringe days. Otherwise, the offset is -5 hours.
This is specific to a conversion from UTC to Eastern time, but additional time zone functions can be added as needed.
USE [YourDatabaseName]
GO
/****** Object: UserDefinedFunction [dbo].[ConvertUTCtoEastern] Script Date: 11/2/2016 5:21:52 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[ConvertUTCtoEastern]
(
#dtStartDate DATETIME
)
RETURNS DATETIME
AS
BEGIN
DECLARE #Working DATETIME
DECLARE #Returned DATETIME
SET #Working = #dtStartDate
SET #Working =
case when month(#Working) between 4 and 10 then dateadd(HH,-4,#Working)
when #Working between '2017-03-12' and '2017-11-05' then dateadd(HH,-4,#Working)
when #Working between '2016-03-13' and '2016-11-06' then dateadd(HH,-4,#Working)
when #Working between '2015-03-08' and '2015-11-01' then dateadd(HH,-4,#Working)
when #Working between '2014-03-09' and '2014-11-02' then dateadd(HH,-4,#Working)
when #Working between '2013-03-10' and '2013-11-03' then dateadd(HH,-4,#Working)
when #Working between '2012-03-11' and '2012-11-04' then dateadd(HH,-4,#Working)
else dateadd(HH,-5,#Working) end
SET #Returned = #Working
RETURN #Returned
END
GO

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