datetime related query in sql server - sql-server

DECLARE #PreviousMonthStart DATETIME
DECLARE #PreviousMonthEnd DATETIME
SET #PreviousMonthStart = DATEADD(m,DATEDIFF(m,0,GETDATE())-1,0)
SET #PreviousMonthEnd = DATEADD(ms,-2,DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
PRINT #PreviousMonthStart
PRINT #PreviousMonthEnd
when executed above query the result set is in the below format
Mar 1 2017 12:00AM
Mar 31 2017 11:59PM
But I need result set in below format
2017-04-01 00:00:00.000
any help

The result of the t-sql is what you want but because you are using PRINT to see the results it is casting the result into varchar before printing it.
If you simply do a select instead of the PRINT it will show you what you want to see.
DECLARE #PreviousMonthStart DATETIME
DECLARE #PreviousMonthEnd DATETIME
SET #PreviousMonthStart = DATEADD(m,DATEDIFF(m,0,GETDATE())-1,0)
SET #PreviousMonthEnd = DATEADD(ms,-2,DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
SELECT #PreviousMonthStart -- Result: 2017-03-01 00:00:00.000
SELECT #PreviousMonthEnd -- Result: 2017-03-31 23:59:59.997
PRINT #PreviousMonthStart -- Result: Mar 1 2017 12:00AM
PRINT #PreviousMonthEnd -- Result: Mar 31 2017 11:59PM

You can add CONVERT with the declared variable with the print statement.
DECLARE #PreviousMonthStart DATETIME
DECLARE #PreviousMonthEnd DATETIME
SET #PreviousMonthStart = DATEADD(m,DATEDIFF(m,0,GETDATE())-1,0)
SET #PreviousMonthEnd = DATEADD(ms,-2,DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0))
PRINT CONVERT(VARCHAR(25),#PreviousMonthStart,120)
PRINT CONVERT(VARCHAR(25),#PreviousMonthEnd,120)
Output:
2017-03-01 00:00:00
2017-03-31 23:59:59

Related

How to get count of number of days left in month from given date

I want the count of number of days from 25/02/2019 in month of February and expected result is 4
I tried using master..spt_values in sql server but did not get expected result
declare #fdays int ,#d date=cast('20190201' as date),#JoinDate date=cast('20190225' as date)
select count(dateadd(dd,number,#d)) from master..spt_values
where type = 'p'
and month(dateadd(dd,number,#d))=month(#d)
and year(dateadd(dd,number,#d))=year(#d)
and cast(GETDate() as date)>= Cast(dateadd(dd,number,#JoinDate) as date )
The result of above code is 28 but I want 4
Please help me to find the expected result
This is simple date arithmetic, you do not need to use spt_values:
declare #d date = '20190225';
select datediff(month,0,#d) as MonthsDiff -- Months since an arbitrary date
,dateadd(month,datediff(month,0,#d)+1,0) as StartOfFollowingMonth -- Add months above +1 to same arbitrary date
,datediff(day,#d,dateadd(month,datediff(month,0,#d)+1,0)) as DaysBetweenGivenDate -- DATEDIFF between given date and start of month from above;
Output:
+------------+-------------------------+----------------------+
| MonthsDiff | StartOfFollowingMonth | DaysBetweenGivenDate |
+------------+-------------------------+----------------------+
| 1429 | 2019-03-01 00:00:00.000 | 4 |
+------------+-------------------------+----------------------+
Try this:
declare #date date='20140603'
select datediff(day, #date, dateadd(month, 1, #date))-day(#date)
Starting with SQL Server 2012, you could just use the EOMONTH function:
SELECT DATEDIFF(DAY, '20190225', EOMONTH ('20190225')) + 1 [thedays]
= 4.

How can I convert YYWW to date format based on day[Ex: Monday's date in given YYWW ] in SqlServer?

I have a column in my table with YYWW format. I need to convert this YYWW and get Monday's date.
For Example:
Input YYWW: 1847
Expected Output: 2018-11-19 [Monday's date in 2018 Week 47]
Thanks in advance
I tried the below but does not work properly
declare #value int = 1519
SELECT CONVERT(VARCHAR(10), DATEADD(YEAR, 2000 + #value / 100-1900, 7 * (#value % 100)-7), 105);
1851 -Expected 17-12-2018[Monday] Works fine for this year 2018
1752 -Expected 25-12-2017[Monday] but shows 24-12-2017 [Sunday]
1652 -Expected 26-12-2016 [Monday] but shows 24-12-2016 [Saturday]
1519 -Expected 04-05-2015 [Monday] but shows 07-05-2015 [Thursday]
Try this:
DECLARE #t table(YYWW char(4))
INSERT #t values('1847'),('1752'),('1652'),('1519')
SELECT
CAST(DATEADD(wk,RIGHT(YYWW,2)+DATEDIFF(d,0,DATEADD(
d,-4,LEFT(YYWW,2)+'0101'))/7,0) as date)
FROM #t
Result:
2018-11-19
2017-12-25
2016-12-26
2015-05-04
EDIT:
To get the requested format DD-MM-YYYY:
SELECT
CONVERT(CHAR(10),DATEADD(wk,RIGHT(YYWW,2)+DATEDIFF(d,0,DATEADD(
d,-4,LEFT(YYWW,2)+'0101'))/7,0),105)
FROM #t
I would, personally, use a calendar table. Then you can do something like:
SELECT YT.YYWW,
CT.[date]
FROM YourTable YT
JOIN CalendarTable CT ON CT.[Year] = '20'+LEFT(YT.YYWW,2)
AND CT.WeekNo = RIGHT(YT.YYWW,2)
AND CT.DayOfWeek = 1; --Assumes Monday is day 1.
I think your calc may be off week 47 of 2018 starts on 2018-11-26 which is a Monday.
in any case the following should work if you disagree with the above simply subtract 1 from the number of weeks
DECLARE #Date date
DECLARE #Year int = 2000 +18
declare #week int = 47
SET #Date = DATEADD(YEAR, #Year - 1900, 0)
SELECT dateadd(ww,#week-1,DATEADD(DAY, (##DATEFIRST - DATEPART(WEEKDAY, #Date) + (8 - ##DATEFIRST) * 2) % 7, #Date))

How to format a date with my own time part in SQL

I'm working on a SQL query which returns a integer which is the number of minutes between two given dates as follows
DATEDIFF(mi, date_one, getdate())
The above query returns difference in two dates in minutes but for getdate() I would want to supply my own time.
For example, consider
date_one= 2015-12-29 13:39:03.000
getdate() return current date and time ie., 2015-12-29 14:33:50.000
But, I want to change time part in getdate() to some 10:00:00.00 so that the getdate() is 2015-12-29 10:00:00.00 by passing an hour integer say 10.
May I know a good way to do that?
This will use getDate, but let you set your own hour. Just replace that second parameter (which is 10 with whichever hour you want). Use this expression in place of getDate() in your dateDiff function.
DATEADD(hh, 10, DATEADD(d, DATEDIFF(d, 0, getDate()), 0))
You can also add minutes, seconds, milliseconds, etc. to get what you need.
Here I am adding 633 minutes to make it 10:33 (change the first parameter to mi for minutes).
select DATEADD(mi, 633, DATEADD(d, DATEDIFF(d, 0, getDate()), 0))
See the documentation for other value for the first parameter: https://msdn.microsoft.com/en-us/library/ms186819.aspx
Here is how to use it:
DATEDIFF(mi, getDate(),
DATEADD(mi, 633, DATEADD(d, DATEDIFF(d, 0, getDate()), 0))
)
This will give you the minutes from the current time to 10:33 on the current day. Here is a sqlfiddle: http://sqlfiddle.com/#!6/9eecb7/5407
I find this function useful:
CREATE FUNCTION [dbo].[StripTimeFromDateTime]
(
#date DateTime
)
RETURNS DateTime
AS
BEGIN
RETURN DATEADD(dd, DATEDIFF(dd, 0, #date), 0)
END
This will knock the time off a datetime leaving it at 00:00:00.000. Then you can:
SELECT DATEADD(hour, 10, dbo.StripTimeFromDateTime(GetDate()))
Notice the example below:
select
cast('2015-12-28 12:15:00' as datetime),
getdate(),
cast(cast(convert(date, getdate()) as varchar(20)) + ' 10:00:00' as datetime);
|----------------------------|----------------------------|----------------------------|
| December, 28 2015 12:15:00 | December, 29 2015 20:42:35 | December, 29 2015 10:00:00 |
An example like the one you used:
with example as (
select cast('2015-12-28 12:15:00' as datetime) as date_one
)
select
date_one,
cast(cast(convert(date, getdate()) as varchar(20)) + ' 10:00:00' as datetime) as myown,
datediff(
mi,
date_one,
cast(cast(convert(date, getdate()) as varchar(20)) + ' 10:00:00' as datetime)
) as minutes
from example;
Result:
| date_one | myown | minutes |
|----------------------------|----------------------------|---------|
| December, 28 2015 12:15:00 | December, 29 2015 10:00:00 | 1305 |
Example on SQLFiddle: http://sqlfiddle.com/#!3/9eecb7/6599
The reason I used varchar is to have flexibility of typing a time such as '10:15:00' or other variations of time.
This one-liner will gives the current date with the time part replaced with the constant you want
select cast(cast(getdate() as date) as datetime) + cast(cast('10:00:00' as time) as datetime)
How this works:
Cast the getdate() result to date and then back to datetime to get the current date without the time.
select cast(cast(getdate() as date) as datetime)
Cast '10:00:00' to time and then to datetime to get 10:00:00 as datetime.
select cast(cast('10:00:00' as time) as datetime)
Add the two
select cast(cast(getdate() as date) as datetime) + cast(cast('10:00:00' as time) as datetime)
That's all
select DATEADD (hh,10, CONVERT(Datetime, CONVERT (date, GETDATE())))
First remove time and then add 10 hours.

SQL Date Range only show data for the last hour

I want to do a mssql date range to return the data for an hour time range. Meaning, I want to return the data for the last hour, but not for the last hour from the current time.
Declare #today datetime
set #today=GETDATE()
select * from table1 where
datetime>= DATEADD(hh,-2,#Today)
For example, the current time is 11:50:00 a.m. I would like the query to return all the data between 10:00:00 a.m. to 10:59:00 a.m. My variables cannot be static. I would like it dynamic, so no matter what time of the day I run the query it only return the last hour data no matter what time is it now. So it could be any time between 11:00:00 a.m. until 11:59:00 a.m., I still want the result to return data from 10 a.m until 10:59 a.m.
Thank you
Here's a slightly simpler way:
DECLARE #d SMALLDATETIME;
SELECT #d = DATEADD(HOUR, DATEDIFF(HOUR, '20000101', GETDATE()) - 1, '20000101');
SELECT #d;
Now you can use #d in your query, e.g.
WHERE col >= #d AND col < DATEADD(HOUR, 1, #d);
This is an open-ended date range. Please don't think about the "end" of the range or consider this a BETWEEN query. BETWEEN 10:00 AND 10:59 is not a very wise approach, because you may miss data from 10:59:00.003 -> 10:59:59.997. Background info on why BETWEEN is evil.
Try this one :
declare #lowerRange datetime =
dateadd(hh,datepart(hour,dateadd(hh,-1,getdate())) ,
cast(cast(getdate() as date) as smalldatetime) )
declare #upperRange datetime = dateadd(hour,1,#lowerRange)
select * from yourtable where yourdate between #lowerRange and #upperRange
This returns an hour range, of the previous hour to now; meaning that if it was 11:35AM, it would return 10 AM to 11 AM:
DECLARE #today DATETIME, #hour DATETIME, #hourtwo DATETIME
SET #today = GETDATE()
-- Test other times
--SET #today = '2013-11-04 11:37.22'
SELECT #hour = DATEADD(hh,-2,#today)
SELECT #hourtwo = DATEADD(hh,-1,#today)
SELECT CONVERT(SMALLDATETIME,ROUND(CAST(#hour as float) * (24/1),0)/(24/1)) AS PreviousHourBegin
SELECT CONVERT(SMALLDATETIME,ROUND(CAST(#hourtwo as float) * (24/1),0)/(24/1)) AS PreviousHourEnd
This should work:
DECLARE #D DATETIME
SET #D = GETDATE()
SELECT #D AS 'Date',
DATEADD(HOUR,-1,DATEADD(MINUTE,-(DATEPART(MINUTE, #D)),DATEADD(SECOND,-(DATEPART(SECOND, #D)),DATEADD(MILLISECOND,-(DATEPART(MILLISECOND, #D)),#D)))) AS 'Range start',
DATEADD(MINUTE,-(DATEPART(MINUTE, #D)),DATEADD(SECOND,-(DATEPART(SECOND, #D)),DATEADD(MILLISECOND,-(DATEPART(MILLISECOND, #D)),#D))) AS 'Range end'
For the date:
2013-11-04 17:35:51.843
This will return a range like:
Start: 2013-11-04 16:00:00.000
End: 2013-11-04 17:00:00.000
For times between 00:00:00-01:00:00 it will get the range 23:00:00-00:00:00 from the previous day.
declare #today datetime
set #today=GETDATE()
select #today, DATEADD(HOUR, -2, DATEADD(HOUR, DATEDIFF(HOUR, 0, #today), 0)), DATEADD(MINUTE, -1, DATEADD(HOUR, -1, DATEADD(HOUR, DATEDIFF(HOUR, 0, #today), 0)))
result:
2013-11-04 17:42:17.933 2013-11-04 15:00:00.000 2013-11-04 15:59:00.000

T-SQL DateTime to Date Conversion - Tolerance

We are attempting to strip the time off a DateTime variable:
DECLARE #Date DateTime
SET #Date = '01Jan2013 23:59:59.998'
PRINT DATEADD(dd, 0, DATEDIFF(dd, 0, #Date ))
SET #Date = '01Jan2013 23:59:59.999'
PRINT DATEADD(dd, 0, DATEDIFF(dd, 0, #Date ))
Result:
Jan 1 2013 12:00AM
Jan 2 2013 12:00AM
Why does 01Jan2013 23:59:59.999 come back as 2nd Jan rather than 1st Jan?
Because there's no .999 and .998 fraction of a second in datetime type. You only have .990, .993 and .997.
So .998 is rounded down to .997, while .999 is rounded up.
Read more about the type.

Resources