Get DateTime with time as 23:59:59 - sql

I'm trying to do a where statement that specifies a DateTime field is between the start and end of the previous month.
To do this, I need to specify that the first day of the previous month has a time of 00:00:00 and the last day of the previous month has a time of 23:59:59.
This second condition is giving me a headache..
Can someone help me out?
Cheers
MSSQL 2008

try:
SELECT DATEADD(ms, -3, '2011-07-20')
This would get the last 23:59:59 for today.
why 3 milliseconds?, this is because Microsoft SQL Server DATETIME columns have at most a 3 millisecond resolution (something that is not going to change). So all we do is subtract 3 milliseconds

You can also use the less than '<' without the equal. So that you don't need 23:59:59.
Eg.
WHERE DateCreated < '20111201 00:00:00'

Try this, it could be helpful for you
I use one of these two ways to work with time portion in DATETIME fields to do comparisons
EX: get a user log for one day, i.e. from Today's date at 12:00:00 AM till Today's date but at 12:00:00 PM
DECLARE #FromDate datetime
DECLARE #ToDate datetime
SET #FromDate = GETDATE()
SET #ToDate = GETDATE()
Print '------------------------ '
PRINT #FromDate
PRINT #ToDate
SET #FromDate = CONVERT(DATETIME, CONVERT(varchar(11),#FromDate, 111 ) + ' 00:00:00', 111)
SET #ToDate = CONVERT(DATETIME, CONVERT(varchar(11),#ToDate, 111 ) + ' 23:59:59', 111)
Print '------------------------ '
PRINT #FromDate
PRINT #ToDate
DECLARE #TEST_FROM DATETIME
SET #TEST_FROM = dateadd(month,((YEAR(#FromDate)-1900)*12)+MONTH(#FromDate)-1,DAY(#FromDate)-1) + ' 12:00:00'
DECLARE #TEST_TO DATETIME
SET #TEST_TO = dateadd(month,((YEAR(#ToDate)-1900)*12)+MONTH(#ToDate)-1,DAY(#ToDate)-1) + ' 23:59:59'
Print '------------------------ '
PRINT #TEST_FROM
PRINT #TEST_TO
This will print the following in SQL Query editor screen
------------------------
Dec 28 2011 3:18PM
Dec 28 2011 3:18PM
------------------------
Dec 28 2011 12:00AM
Dec 28 2011 11:59PM
------------------------
Dec 28 2011 12:00PM
Dec 28 2011 11:59PM
References
The way using the convert is from my experience, the other way is from this link http://weblogs.sqlteam.com/jeffs/archive/2007/01/02/56079.aspx
Have fun :)

Try this query for using Datetime datatype to get
2018-01-29 23:59:59.997
select dateadd(ms, -3, (dateadd(day, +1, convert(varchar, GETDATE(), 101))))

declare #myDate DateTime, #lastMonth DateTime, #thisMonth DateTime
set #myDate = GETDATE()
set #lastMonth = DateAdd(month, -1, CAST(#myDate as Date))
set #thisMonth = DateAdd(day, -DatePart(day, #myDate)+1, CAST(#myDate as Date))
select #myDate as MyDate, DateAdd(day, -DatePart(day, #lastMonth) + 1, #lastMonth) FirstDay, DateAdd(second, -1, #thisMonth) LastDay
Results

Try This:
SELECT dateadd(millisecond,-1,cast(cast(getdate() AS date) AS datetime2))

SELECT DATEADD(ms, -2, CAST(CONVERT(date, DATEADD (DAY,1,getdate())) AS varchar(10)))
output: yyyy-mm-dd 23:59:59.997
2020-08-31 23:59:59.997

I hope someone finds this useful
declare #TodaysDate smalldatetime
declare #TodaysDatepm smalldatetime
First I get the date and Time as of Midnight i.e 16/05/2021 12:00 am
set #TodaysDate = DATEADD(minute, 0,CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS datetime))
Then I add 23hours and 59 minutes onto it i.e (60*23)+59
Which gives 1439, from there I use the the dateadd function
set #TodaysDatepm =DATEADD(minute, 1439, #TodaysDate)
This will always print out midnight of what you set in #TodaysDate
Print #TodaysDatepm

Related

Number of days left in current month

Number of days left in a given month
How do I find the number of days left in the current month?
Example if current month is November and todays date is 16/11/2016
The Numbers of days in month – Elapse days = ? I want to do it dynamically
In my example 30 – 16 = 14
declare #date date
set #date='16 Nov 2016'
select datediff(day, #date, dateadd(month, 1, #date)) - 16 AS DaysLeft
Since this is sql server 2008 you can't use EOMonth (that was introduced in 2012 version).
You have to do some date adds and date diffs:
SELECT DATEDIFF(DAY,
GETDATE(),
DATEADD(MONTH,
1,
DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE())
)
) - 1
explanations:
DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE()) gets the first day of the current month, the wrapping DATEADD adds one month, and the wrapping DATEDIFF returns the number of days between the current date and the first date of the next month. This is why you need to subtruct 1 to get the correct number of days.
--For SQL 2012 And Above Version Use Below Query to Get Count Of Days Left In A Month
DECLARE #date DATE
SET #date=GETDATE()
SELECT DATEDIFF(DAY, #date,EOMONTH(#date))
-- And for Sql Server 2008 Use Below Query to Get Count of Days Left for the Month
DECLARE #date Date
SET #date=GETDATE()
SELECT DATEDIFF(DAY, #date, DATEADD(MONTH, 1, #date)) - DATENAME(DAY,GETDATE())
AS DaysLeft
Simply use the Datepart function:
declare #date date
set #date='16 Nov 2016'
select datediff(day, #date, dateadd(month, 1, #date)) - Datepart(DAY,#date)
Change your date to getdate()
declare #date date
set #date=GETDATE()
select datediff(day, #date, dateadd(month, 1, #date)) - DATENAME(DAY,GETDATE())
AS DaysLeft
DECLARE #date DATE SET #date='16 Nov 2016' SELECT DATEDIFF(DAY, #date,EOMONTH(#date))
Use EOMONTH and DATEDIFF functions
declare #date date
set #date='16 Nov 2016'
select datediff(day,#date,eomonth(#date)) as days_left
Use below solution For Below versions of sql server 2012
DECLARE #DATE DATE
SET #DATE='16 NOV 2016'
SELECT DATEDIFF(DAY,#DATE,DATEADD( MM,DATEDIFF(MM,0,#DATE)+1,0))-1 AS DAYS_LEFT
FUNCTION example
CREATE Or ALTER FUNCTION ReturnDaysLeftInMonth(#Date Date)
RETURNS Int
AS
BEGIN
RETURN DATEDIFF(DAY, #Date, EOMONTH(#Date)) + 1
END
Or use
Declare #Date Date
Set #Date=GETDATE()
DATEDIFF(DAY, #Date, EOMONTH(#Date)) + 1

How to get date to be the same day and month from one variable but in the year based on another variable?

I am trying to get the specific day of a Year.
Here's what I have tried till now:-
-- Declare few variables
DECLARE #Currentdate AS DATETIME
DECLARE #DueDate AS DATETIME
DECLARE #NewDate AS DATETIME
-- Set the variables properly, just for testing
SET #Currentdate = GETDATE()
SET #DueDate = DATEADD(MONTH, 2, DATEADD(YEAR, 1, #Currentdate))
-- Check the output
SELECT #Currentdate -- 2013-09-30 00:00:00.000
SELECT #DueDate -- 2014-11-30 00:00:00.000
So, I want to get the #NewDate based on the #Currentdate year.
For this I tried:-
SELECT #NewDate = DATEADD(DAY, DAY(DATEDIFF(day, 1, #DueDate)), DATEADD(MONTH, DATEDIFF(MONTH, 0, #Currentdate), 0))
SELECT #NewDate -- 2013-09-30 00:00:00.000
But it didn't worked. :(
My expected result is like:
-- 2013-11-30 00:00:00.000
-- Having the due date month and date same, but the year as current date one.
Any help is appreciated!
UPDATE
Sorry for all the confusion I have created. My question in simple words is:-
I want to get the a new date variable having the date and the month same as #DueDate variable but the year as given in the #Currentdate variable.
I hope that would clear things up a bit.
If the question is "given I have a particular datetime value in one variable, can I set another variable to be for the same day and month but in the current year" then the answer would be:
declare #DueDate datetime
declare #NewDate datetime
set #DueDate = '20141130'
--Need to set #NewDate to the same month and day in the current year
set #NewDate = DATEADD(year,
--Here's how you work out the offset
DATEPART(year,CURRENT_TIMESTAMP) - DATEPART(year,#DueDate),
#DueDate)
select #DueDate,#NewDate
I want to get the a new date variable having the date and the month same as #DueDate variable but the year as given in the #Currentdate variable.
Well, that's simply the above query with a single tweak:
set #NewDate = DATEADD(year,
--Here's how you work out the offset
DATEPART(year,#Currentdate) - DATEPART(year,#DueDate),
#DueDate)
Try this instead ?
DECLARE #Currentdate AS DATETIME
DECLARE #DueDate AS DATETIME
-- Set the variables properly, just for testing
SET #Currentdate = GETDATE()
SET #DueDate = DATEADD(MONTH, 2, DATEADD(YEAR, 1,
DateAdd(day, datediff(day, 0, #currentDate), 0)))
-- Check the output
SELECT #Currentdate -- 2013-09-30 18:32:35.310
SELECT #DueDate
Using DateAdd(day, datediff(day, 0, #DateTime), 0) strips off the time portion. You should also check out this SO Question/answer.
Try this one:
CAST(CAST( -- cast INT to VARCHAR and then to DATE
YEAR(GETDATE()) * 10000 + MONTH(#DueDate) * 100 + DAY(#DueDate) -- convert current year + #DueDate's month and year parts to YYYYMMDD integer representation
+ CASE -- change 29th of February to 28th if current year is a non-leap year
WHEN MONTH(#DueDate) = 2 AND DAY(#DueDate) = 29 AND ((YEAR(GETDATE()) % 4 = 0 AND YEAR(GETDATE()) % 100 <> 0) OR YEAR(GETDATE()) % 400 = 0) THEN 0
ELSE -1
END
AS VARCHAR(8)) AS DATE)

ADD time 23:59:59.999 to end date for between

I have been having an issue with using the following:
Column_Name BETWEEN #StartDate AND #EndDate.
This is because the #EndDate = 00:00:00.000 for the time, which doesn't pick up all the values for that day.
How would I convert the #EndDate (Always 00:00:00.000) to always be Date + 23:59:59.999?
One option that avoids needing to add EndDate + 23:59:59.999 is to not use the between comparison and instead use column_name >= #StartDate and column_name < #EndDate +1
Please note the accuracy and rounding of the DATETIME type in SQL Server 2005:
datetime values are rounded to increments of .000, .003, or .007 seconds
SQL Server 2008 introduced the DATETIME2 type which has an accuracy of 100 nanoseconds. So in SQL Server 2008 you could do:
DECLARE #d DATETIME = '2011-10-07 00:00:00.000'
SELECT DATEADD(MS, -1, DATEADD(D, 1, CONVERT(DATETIME2, #d)))
Alternatively you may want to avoid the BETWEEN operator in this case:
#StartDate <= Column_Name AND Column_Name < DATEADD(D, 1, #EndDate)
Since the advent of datetime2 datatype, I have been struggling with this problem. To calculate the end of day as a datetime2 datatype I add the number of seconds in a day to the =date= then subtract 100 nanoseconds. Voila:
declare #bod datetime2
declare #eod datetime2
set #bod = cast (GETDATE() as DATE)
set #eod = DATEADD(ns, -100, DATEADD(s, 86400, #bod))
print #bod
print #eod
-- answer:
2013-12-01 00:00:00.0000000
2013-12-01 23:59:59.9999999
Now I'm off to datetimeoffset data type.
You can change the time in a date like this (I'm using getdate() as an example):
select cast(convert(char(8), getdate(), 112) + ' 23:59:59.99' as datetime)
Explanation:
convert(char(8), getdate(), 112) converts the date to yyyymmdd format (as string).
Then you can just append the desired time, and convert the whole string to datetime again.
EDIT:
It slows the performance when you do the casting on a database column, yes.
But he has a datetime variable and he just uses the casting to change the time in the variable once
--> I see no performance issue if he uses my code to change his #EndDate variable.
Valid point, however. Casting is not a good solution in all situations.
You could also do this:
select #endDate = dateadd(ms,-3,dateadd(day,1,DATEADD(dd, DATEDIFF(dd,0,#endDate), 0)))
when #endDate is '5/3/2013'
--Execution / post date is 1 Feb. 2020
-- sql server this month start and end
select DATEADD(month, DATEDIFF(month, 0, getdate()), 0) -- 2020-02-01 00:00:00.000
select DATEADD(second,-1, datediff(day,0,EOMONTH(getdate()))+1) -- 2020-02-29 23:59:59.000
-- sql server this day start and end
select DATEADD(day, DATEDIFF(day, 0, getdate()), 0) -- 2020-02-01 00:00:00.000
select DATEADD(second,-1, datediff(dd,0,getdate())+1) -- 2020-02-01 23:59:59.000
-- sql server last 30 days start and end
select DATEADD(day, -30, DATEDIFF(day, 0, getdate())) -- 2020-01-02 00:00:00.000
select DATEADD(second,-1, datediff(dd,0,getdate())+1) -- 2020-02-01 23:59:59.000
You can use between if your end date is set to 00:00:00 of the next day:
ColumnName between #StartDate and convert(datetime, convert(date, #EndDate + 1))
This converts the next day to a date, which removes the hours information, then you convert it back to a datetime which adds default hour information: 00:00:00.
You can use any variant of the date from parts functions. For example, let's use DATETIMEFROMPARTS:
DECLARE #d DATETIME2(0) = '2011-10-07 04:32:12.000';
SELECT DATETIMEFROMPARTS(YEAR(#d), MONTH(#d), DAY(#d), 23, 59, 59, 0);
-- 2011-10-07 23:59:59
I first convert the original datetime to begin of the day, then add hours and seconds to it:
DECLARE #start DATETIME, #end DATETIME
SET #start = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
SET #end = DATEADD(HOUR, 23, DATEADD(n, 59, #start))
PRINT #start
PRINT #end
Oct 27 2017 12:00AM
Oct 27 2017 11:59PM

Set time portion of a datetime variable

I am working on a query that will be an automated job. It needs to find all the transactions between 8 PM and 8 PM for the last day. I was thinking of doing something like this
DECLARE #start_date DATETIME
DECLARE #end_date DATETIME
SET #start_date = DATEADD(DAY, -2, GETDATE())
SET #end_date = DATEADD(DAY, -1, GETDATE())
For an automated query this works good at figuring out the date portion. But the TIME portion of the variable is the current time that the query executes. Is there a quick simple way to hard code the time portion of both variables to be 8:00 PM?
DECLARE #start_date DATETIME
DECLARE #end_date DATETIME
SET #start_date = DATEADD(hour, 20, DATEDIFF(DAY, 2, GETDATE()))
SET #end_date = #start_date + 1
select #start_date, #end_date
This will also work:
DECLARE #start_date datetime
DECLARE #end_date datetime
SET #start_date = LEFT(CONVERT(nvarchar, DATEADD(DAY, -2, GETDATE()), 120), 11) + N'20:00:00'
SET #end_date = #start_date + 1
select #start_date, #end_date
Although cyberkiwi's answer is very clever! =)
I needed to pull a date from the database and append 3:00 Pm to it. I did it this way
select dateadd(hour, 15, datediff(day, 0, myDatabaseDate))
from dbo.myDatabaseTable
where myDatabaseId = 1
The result that it returned was 2017-10-01 15:00:00.000. The date in the database is 2017-10-01. The solution that I proposed was to keep my current date. I added 0 days to my existing date. I gave it 15:00 hours and it worked like a charm.
In case of just updating a particular part of the datetime you can use SMALLDATETIMEFROMPARTS like:
UPDATE MyTable
SET MyDate = SMALLDATETIMEFROMPARTS(YEAR(MyDate), MONTH(MyDate), DAY(MyDate), <HoursValue>, <MinutesValue>)
In other cases it may be required to copy parts of datetime to other or update only certain parts of the datetime:
UPDATE MyTable
SET MyDate = SMALLDATETIMEFROMPARTS(YEAR(MyDate), MONTH(MyDate), DAY(MyDate), DATEPART(hour, MyDate), DATEPART(minute, MyDate))
Refer SQL Server Date/Time related API references for more such functions
DECLARE #start_date DATETIME = DATEADD(HOUR, 20, DATEADD(MINUTE, 00, CONVERT(DATETIME, CONVERT(DATE, GETDATE())))) - 2
DECLARE #end_date DATETIME = DATEADD(HOUR, 20, DATEADD(MINUTE, 00, CONVERT(DATETIME, CONVERT(DATE, GETDATE())))) - 1
Notes:
GETDATE() + X is the equivalent of DATEADD(DAY, X, GETDATE()).
Converting a DATEIME to a DATE and then back to a DATETIME again sets the time to midnight i.e. 00:00:00.000.
Seperate SET and DECLARE statements are unnecessary, but just in case it helps later, variables may be set as part of a SELECT statement too.
I had to do something similar, create a procedure to run from a certain time the previous day to a certain time on the current day.
This is what I did to set the start date to 16:30 on the previous day, basically subtract the parts you don't want to get them back to 0 then add the value that you want it to be.
-- Set Start Date to previous day and set start time to 16:30.00.000
SET #StartDate = GetDate()
SET #StartDate = DateAdd(dd,- 1, #StartDate)
SET #StartDate = DateAdd(hh,- (DatePart(hh,#StartDate))+16, #StartDate)
SET #StartDate = DateAdd(mi,- (DatePart(mi,#StartDate))+30, #StartDate)
SET #StartDate = DateAdd(ss,- (DatePart(ss,#StartDate)), #StartDate)
SET #StartDate = DateAdd(ms,- (DatePart(ms,#StartDate)), #StartDate)
Hope this helps someone.

Playing with Date Time in SQL Server

I am building an SSRS report.
In the report, the week always runs from Monday - Sunday.
And I want to find out the START and END dates of prior two weeks.
For example,
If current date = Jan 1, 2011
-- current week = Dec 27, 2010 to Jan 2, 2011
-- previous week = Dec 20, 2010 to Dec 26, 2010
I have tried the following, but seems like it fails when when current day = Sunday
DECLARE #DT DATETIME
DECLARE #Offset INT
DECLARE #CM DATETIME
DECLARE #PM DATETIME
DECLARE #PS DATETIME
--SET #DT = GETDATE()
SET #DT = '11/14/2010' -- Monday
SET #Offset = (DATEPART(WEEKDAY, #DT) - 2) * -1
SET #CM = DATEADD(DAY, #Offset, #DT)
SET #PM = DATEADD(DAY, -7, #CM)
SET #PS = DATEADD(DAY, -1, #CM)
SELECT #Offset AS Offset, #DT AS Date, #CM AS Monday, #PM AS [Previous Monday], #PS AS [Previous Sunday], DATEPART(WK, #PM) AS Week
How can I fix it?
Add a [Calendar] table to your DB with all the dates you need precalculated. You can then include fields with the day name, number, holiday etc. and simply look up the values you need.
It's much simpler than playing with DATEADD
A useful article on calendar tables: Why should I consider using an auxiliary calendar table?
Not sure if this is the most elegant solution but you could do a case statement with your #offset like this:
SET #offset = CASE WHEN DATEPART(weekday, #today) >= 2
THEN -(DATEPART(weekday, #today) - 2)
ELSE -(DATEPART(weekday, #today) + 5)
END
I believe it works for all cases.