quote: Originally posted by robvolk
Just out of curiosity, what about date and datetime2?
Wonder if he knows why 1753 was the original cutoff.
The same basic logic works with DATE and DATETIME2, but you have to explicitly cast everything, and the base year changes to 0001.
Of course the value of this for very old dates is debatable when you consider the change from the Julian to the Gregorian calendar, but I think if you are going to call it the last Sunday of the month, then it should actually be the last Sunday of the month.
But that's just my absolutely foolish tendency to drastically over-design talking.  I guess you can blame that on my fondness for code that always works.
select
a.DT,
LastDayofMonth =
dateadd(mm,datediff(mm,convert(date,'00011231'),a.DT),convert(date,'00011231')),
LastSundayofMonth =
dateadd(dd,(datediff(dd,convert(date,'00010107'),
dateadd(mm,datediff(mm,convert(date,'00011231'),a.DT),convert(date,'00011231'))
)/7)*7,convert(date,'00010107'))
from
( -- Test data
select DT = convert(date,'00010101') union all
select DT = convert(date,'99991231') union all
select DT = convert(date,getdate()) union all
select DT = convert(date,dateadd(mm,-2,getdate())) union all
select DT = convert(date,dateadd(mm,-1,getdate())) union all
select DT = convert(date,dateadd(mm,1,getdate())) union all
select DT = convert(date,dateadd(mm,2,getdate())) union all
select DT = convert(date,dateadd(mm,3,getdate())) union all
select DT = convert(date,dateadd(mm,4,getdate())) union all
select DT = convert(date,dateadd(mm,5,getdate())) union all
select DT = convert(date,dateadd(mm,6,getdate())) union all
select DT = convert(date,dateadd(mm,7,getdate())) union all
select DT = convert(date,dateadd(mm,8,getdate())) union all
select DT = convert(date,dateadd(mm,9,getdate())) union all
select DT = convert(date,dateadd(mm,10,getdate())) union all
select DT = convert(date,dateadd(mm,11,getdate()))
) a
order by
a.DT
DT LastDayofMonth LastSundayofMonth
---------- -------------- -----------------
0001-01-01 0001-01-31 0001-01-28
2012-12-13 2012-12-31 2012-12-30
2013-01-13 2013-01-31 2013-01-27
2013-02-13 2013-02-28 2013-02-24
2013-03-13 2013-03-31 2013-03-31
2013-04-13 2013-04-30 2013-04-28
2013-05-13 2013-05-31 2013-05-26
2013-06-13 2013-06-30 2013-06-30
2013-07-13 2013-07-31 2013-07-28
2013-08-13 2013-08-31 2013-08-25
2013-09-13 2013-09-30 2013-09-29
2013-10-13 2013-10-31 2013-10-27
2013-11-13 2013-11-30 2013-11-24
2013-12-13 2013-12-31 2013-12-29
2014-01-13 2014-01-31 2014-01-26
9999-12-31 9999-12-31 9999-12-26
select
a.DT,
LastDayofMonth =
dateadd(mm,datediff(mm,convert(datetime2,'00011231'),a.DT),convert(datetime2,'00011231')),
LastSundayofMonth =
dateadd(dd,(datediff(dd,convert(datetime2,'00010107'),
dateadd(mm,datediff(mm,convert(datetime2,'00011231'),a.DT),convert(datetime2,'00011231'))
)/7)*7,convert(datetime2,'00010107'))
from
( -- Test data
select DT = convert(datetime2,'00010101') union all
select DT = convert(datetime2,'99991231') union all
select DT = convert(datetime2,getdate()) union all
select DT = convert(datetime2,dateadd(mm,-2,getdate())) union all
select DT = convert(datetime2,dateadd(mm,-1,getdate())) union all
select DT = convert(datetime2,dateadd(mm,1,getdate())) union all
select DT = convert(datetime2,dateadd(mm,2,getdate())) union all
select DT = convert(datetime2,dateadd(mm,3,getdate())) union all
select DT = convert(datetime2,dateadd(mm,4,getdate())) union all
select DT = convert(datetime2,dateadd(mm,5,getdate())) union all
select DT = convert(datetime2,dateadd(mm,6,getdate())) union all
select DT = convert(datetime2,dateadd(mm,7,getdate())) union all
select DT = convert(datetime2,dateadd(mm,8,getdate())) union all
select DT = convert(datetime2,dateadd(mm,9,getdate())) union all
select DT = convert(datetime2,dateadd(mm,10,getdate())) union all
select DT = convert(datetime2,dateadd(mm,11,getdate()))
) a
order by
a.DT
DT LastDayofMonth LastSundayofMonth
---------------------- ---------------------- ----------------------
0001-01-01 00:00:00.00 0001-01-31 00:00:00.00 0001-01-28 00:00:00.00
2012-12-13 23:15:29.31 2012-12-31 00:00:00.00 2012-12-30 00:00:00.00
2013-01-13 23:15:29.31 2013-01-31 00:00:00.00 2013-01-27 00:00:00.00
2013-02-13 23:15:29.31 2013-02-28 00:00:00.00 2013-02-24 00:00:00.00
2013-03-13 23:15:29.31 2013-03-31 00:00:00.00 2013-03-31 00:00:00.00
2013-04-13 23:15:29.31 2013-04-30 00:00:00.00 2013-04-28 00:00:00.00
2013-05-13 23:15:29.31 2013-05-31 00:00:00.00 2013-05-26 00:00:00.00
2013-06-13 23:15:29.31 2013-06-30 00:00:00.00 2013-06-30 00:00:00.00
2013-07-13 23:15:29.31 2013-07-31 00:00:00.00 2013-07-28 00:00:00.00
2013-08-13 23:15:29.31 2013-08-31 00:00:00.00 2013-08-25 00:00:00.00
2013-09-13 23:15:29.31 2013-09-30 00:00:00.00 2013-09-29 00:00:00.00
2013-10-13 23:15:29.31 2013-10-31 00:00:00.00 2013-10-27 00:00:00.00
2013-11-13 23:15:29.31 2013-11-30 00:00:00.00 2013-11-24 00:00:00.00
2013-12-13 23:15:29.31 2013-12-31 00:00:00.00 2013-12-29 00:00:00.00
2014-01-13 23:15:29.31 2014-01-31 00:00:00.00 2014-01-26 00:00:00.00
9999-12-31 00:00:00.00 9999-12-31 00:00:00.00 9999-12-26 00:00:00.00
CODO ERGO SUM |