DECLARE @d TABLE(d DATE);
INSERT @d(d) VALUES('20150330'),('20150331'),
('20150430'),('20150531'),('20150526'),
('20160229'), -- Leap day: test "Today of last year" and "Yesterday of last year"
-- Month after leap day: test "Today of last month" and "Yesterday of last month"
('20160329'),('20160330'),('20160331'),
-- March 1st in possible leap year: test "Yesterday"
('20160301'), -- test regular leap year
('20000301'), -- test century divisible by 400
('19000301'), -- test century not divisible by 400 (not a leap year)
-- March 1st in year AFTER possible leap year: test "Yesterday of last year"
('20170301'), -- test regular leap year
('20010301'), -- test century divisible by 400
('19010301'); -- test century not divisible by 400 (not a leap year)
SELECT
[Today] = d,
[Today of last year] = DATEADD(YEAR, -1, d),
[Today of last month] = DATEADD(MONTH, -1, d),
[Yesterday] = DATEADD(DAY, -1, d),
[Yesterday of last year] = DATEADD(DAY, -1, DATEADD(YEAR, -1, d)),
[Yesterday of last month] = DATEADD(DAY, -1, DATEADD(MONTH, -1, d))
FROM @d;
真的不需要任何技巧来处理闰年,但这取决于您期望的结果。通常你只是先减去较大的部分,所以在减去一天之前减去一个月,而不是相反。
这些是否会产生您不期望的结果?如果是这样,哪些对您来说是“错误的”,为什么?
如果您想以不同方式处理闰年、节假日、周末等,也可以考虑使用日历表。您真正需要做的是充分理解并解释您的要求。许多月份有 31 天,尤其是闰年,“今天或昨天上个月或上年”的每种可能组合都可以有多种解释。
昨天:
去年的今天:
上个月的今天:
去年的昨天:
上个月的昨天:
奇数日期(尤其是闰年)的附加技巧:
(如果上一年的日期不存在,请使用之前的日期)