Adding time and date - sql

I have two columns in MSSQL 2008 R2: Workingdate and Startime.
Due to a mistake in the design of the application starttime was not defined as date+time, but only time (e.g. 1899-12-30 16:00:00.000 for 4:00 PM)
Now, I am facing a Problem that I cannot add date and time.
Why is
select convert(datetime,'2015-07-01 00:00:00.000') + convert(datetime,'1899-12-30 16:00:00.000')
2015-06-29 16:00:00.000 and not 2015-07-01 16:00:00.000
Thanks your help
Sorry: I found the solution: Date comes from VBA and the first day is 1899-12-30 and not 1900-01-01 as in SQL !!! Therefore I have to add +2 !!

Try this:
select dateadd(second,
datepart(hour,'1899-12-30 16:00:00.000') * 3600 +
datepart(minute,'1899-12-30 16:00:00.000') * 60 +
datepart(second,'1899-12-30 16:00:00.000'),
'2015-07-01 00:00:00.000')
The idea is to use DATEADD function to add the needed time in seconds to your base date (2015-07-01 00:00:00.000). In order to convert the record time to seconds we are using the DATEPART function three time to extract the hours, the minutes and the seconds from your record date.
To fix the date in your table you can use something like this:
UPDATE [dbo].[MyTable]
SET [Date] = DATEADD(SECOND, DATEPART(HOUR, [Date]) * 3600 + DATEPART(MINUTE, [Date]) * 60 + DATEPART(SECOND, [Date], '2015-07-01 00:00:00.000');

You can't easily use dateadd for this, the easy way is adding the time from one column with the datetime of the other column like this:
SELECT
cast('1899-12-30 16:00:00.000' as time)+
cast('2015-07-01 00:00:00.000' as datetime)
Result:
2015-07-01 16:00

Normally i would always use DATEADD for this type of operation.
Hope it helps

Related

SQL Server - Check if given date+time is between two datetime variables by exact date+time

I have two datetime columns in a DB table: #Start and #End.
Both columns contain the date and time, for example:
#Start: 2018-10-01 19:00:00
#End: 2018-10-10 23:59:00
I want to know if the current date is exactly between both datetimes considering the dates and the times.
So, 2018-10-08 16:37 and 2018-10-10 23:59:00 would match this range
and 2018-10-11 00:00:00 would not.
(In this case this date is one minute later than the End date, so it is not between my datetime range).
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN Start AND End
I don't use GETDATE() in real code, I use an argument. The problem is that current date argument may contain seconds and milliseconds like 23:59:59.123. My code treats such date as not conforming given range. But I don't care about s/ms.
Is there a workaround?
Update:
The precision I want to achieve is in minutes. So I do not even need to take in account the seconds nor the milliseconds. The date time format I would be working on would be 'yyyy-MM-dd hh-mm' but I do not know how to use the BETWEEN clause converting the Start and End to the shown format so I can compare the dates.
You would seem to want this logic:
WHERE GETDATE() >= Start
AND GETDATE() < DATEADD(minute, 1, End)
Assuming that the time part of End is 23:59:00 it covers all possible values between 23:59:00 and 23:59:59.999...999.
SELECT Id FROM Table1 WHERE GETDATE() BETWEEN '2018-10-01 19:00:00' AND '2018-10-10 23:59:00'
TRY
SELECT Id FROM Table1 WHERE
CONVERT(varchar(16),GETDATE(),121) BETWEEN
CONVERT(varchar(16),[Start], 121)
AND
CONVERT(varchar(16),[END],121);
Example of rounding without strings
DECLARE #GetDateMinutes as datetime2;
DECLARE #X as datetime2 = getdate();
--round to minutes, could be made into a function
SET #GetDateMinutes = dateadd(minute,datepart(minute,#x),dateadd(hour, datepart(hour,#x),cast(CAST(#x as date) as datetime2)))
select #x, #GetDateMinutes
Truncate the seconds using the technique described here to avoid all string conversions, then just do your comparison. Here's a fully contained example that uses cross apply and values to encapsulate the truncation logic for start and end:
-- truncate minutes from current date time
declare #currentDateTime datetime2(0) = DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), N'2018-10-01 23:58:32.912')), 0);
select #currentDateTime as CurrentDateTime
, a.*
from (values -- create a table of dummy values
(Convert(datetime2(3), N'2018-10-01 19:48:14.735'), Convert(datetime2(3), N'2018-10-10 02:00:00.000'))
, (Convert(datetime2(3), N'2018-10-01 22:43:19.532'), Convert(datetime2(3), N'2018-11-01 12:17:26.663'))
) as a (StartDateTime, EndDateTime)
cross apply (values(
-- truncate minutes from start date time
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.StartDateTime)), 0)
-- truncate minutes from end date time
, DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), a.EndDateTime)), 0)
)) as b (StartDateTimeWithoutSeconds, EndDateTimeWithoutSeconds)
where #currentDateTime between b.StartDateTimeWithoutSeconds and b.EndDateTimeWithoutSeconds;
Your data appears to already have the s/ms truncated from start and end but figured I'd apply the same logic to all values involved just to be consistent. Here's the formula for stripping s/ms without all the "noise" from the example:
DateAdd(minute, DateDiff(minute, 0, Convert(datetime2(0), <SomeDateTime>)), 0)

How to change both date and time in a datetime in SQL

I try to set the time and date in my query based one the following conditions:
if time in MyDate < 9:00 then set the time to 9:00
If time in 9:00 < MyDate < 15:00 then set the time to 16:00
If time is MyDate > 15:00 then set the time to 9:00 and the day to day+1
I have the two first conditions in place and works fine, but cannot combine changes in both time and date. How can I do that?
The code below works fine for the two first conditions!
Case When cast(MyDate as TIME) < '09:00:00' Then DATEADD(Hour, 9, CAST(CAST(PayoutDtApplication As Date) As Datetime))
Case When cast(MyDate as TIME) < '09:00:00' Then DATEADD(Hour, 9, CAST(CAST(PayoutDtApplication As Date) As Datetime))
THanks
This is a guess, based on the following comment:
this numbers can varries based on the data I get, just wanted to say I need to set the time to 9:00 and day+1 for all dates I get. I have different dates.
I'm guessing that regardless of the time, the OP wants to change the value to the following date at 09:00:00.
If so, one way to achieve it would be:
SELECT DATEADD(HOUR, 33, CONVERT(date,YourDateColumn)) AS NewDate
FROM YourTable;
Again, this is guesswork. If the OP elaborates, I'll be happy to expand my answer, or remove it if it's irrelevant.
Edit: Based on the OP's new logic from their edit:
CREATE TABLE #Sample (YourDate datetime2(0));
INSERT INTO #Sample
VALUES ('2018-05-09T08:57:00'),
('2018-05-09T14:26:37'),
('2018-05-09T19:24:01');
GO
SELECT YourDate,
CASE WHEN CONVERT(time, YourDate) < '09:00:00' THEN DATEADD(HOUR,9,CONVERT(datetime2(0),CONVERT(date,YourDate)))
WHEN CONVERT(time, YourDate) > '15:00:00' THEN DATEADD(HOUR,33,CONVERT(datetime2(0),CONVERT(date,YourDate)))
ELSE DATEADD(HOUR,15,CONVERT(datetime2(0),CONVERT(date,YourDate))) END AS NewDate
FROM #Sample;
GO
DROP TABLE #Sample;
The double CONVERT (CONVERT(datetime2(0),CONVERT(date...) is because the data type date isn't compatible with DATEADD(HOUR.... I have used datetime2 as this should be used over datetime now.

How to find out the records between AM and PM

I need to find out the records between AM and PM from the below table.
for eg: If I Enter START TIME AS 7.00 AM AND END TIME AS 4.00 PM, I need to get below records.
Start Time and End Time data is in varchar datatype with 12 hour format. How do i distinguish between AM and PM in the search criteria. Is there any inbuilt function to extract the time in 24 hour format in sql server?. Thanks in advance.
Convert your fields into time format and then compare it.
SELECT CONVERT(time, '07:01 PM')
SQL Fiddle
Now, you cane write your query like below
select * from yourtable where CONVERT(time, starttime) >= CONVERT(time, '07:00 AM') AND CONVERT(time, endtime) <= CONVERT(time, '04:00 PM')

Format the datetime to get date and hour information

How to get the date and hour information for a given datetime object in Transact-SQL?
E.g. 2014-12-18 21:00:00 for 2014-12-18 21:24:05.
I need to truncate off all parts after the hour - i.e. minutes, seconds, and partial seconds.
For SQL Server:
Select DATEPART(HOUR, [date]) + ":" + DATEPART(MINUTE, [date]);
Oracle:
Select TO_CHAR([date], 'HH:MI') From...
SELECT
CONVERT(TIME,GETDATE()) AS TimeOnly,
CONVERT(DATE,GETDATE(),101) AS DateOnly
GO
Replace the GETDATE() function with whatever you need.

How to assign current date with specific time to column?

How do i assign current date with a specific time?
let's say 8:00:00 AM to Column EXIT_DT of datatype datetime??
I have tried GETDATE() AS EXIT_DT but it gives me current datetime. I am using Sql server 2005. Any help?
Lets say Today is 1/3/2013 and i want my result to return as a datetime datatype with value 1/3/2013 8:00:00 AM. If i run the statement ytd, the result will be 1/2/2013 8:00:00 AM
This formula will always produce 08:00 for the day it is called, and avoids string manipulation:
select DATEADD(day,DATEDIFF(day,'20010101',GETDATE()),'2001-01-01T08:00:00')
Try to avoid solutions that convert to and from strings - treating datetime values as strings is one of the largest sources of bugs.
It works by computing the number of days (as an integer) that have elapsed since 1st January 2001. It then adds that same number of days to 08:00 on 1st January 2001.
You can try this :
DECLARE #dt datetime;
SET #dt=CONVERT(DateTime, CONVERT(VARCHAR,GETDATE(),101)+' 8:00:00')
SELECT CONVERT(VARCHAR, #dt, 101)+' '+ LTRIM(RIGHT(CONVERT(VARCHAR(20),#dt, 100), 7))
Visit http://www.sql-server-helper.com/tips/date-formats.aspx for datetime formats.
Use Convert along with getdate() to get specific formats.
ex:
SELECT CONVERT(VARCHAR(30),GETDATE(),113)
This is a bit stupid, but it works
select cast(cast(getdate() as date) as datetime) + '08:00:00'
it casts the getdate() to date thus losing the hours, than it casts it to datetime and adds 8 hours.
If you want to avoid implicit conversion of varchar to datetime, you could use this version:
select cast(cast(getdate() as date) as datetime)
+ convert(datetime,'08:00:00',114)
This is also working. (1). convert today's date to ISO format (yyyymmdd) (2). add the time, (3). convert back to datetime
Select convert(datetime, convert(varchar, getdate(),112) + ' ' + '8:00:00AM')
--Results
2013-01-03 08:00:00.000
If you need in specific format you need to convert back to varchar again.
-- AM/PM --
SELECT TO_CHAR(sysdate, 'MM/DD/YYYY HH:MI:SS AM') FROM dual
/
-- 24 hrs format --
SELECT TO_CHAR(sysdate, 'MM/DD/YYYY HH24:MI:SS') FROM dual
/