如何解决计算列日期闰年问题
我有一张姓名和相关生日的表格。我可以通过匹配数据库中的生日和当前日期之间的 MONTH 和 DAY 日期部分来检索今天生日的每个人的姓名。但是,我需要提取未来两周内所有生日的“期待”列表。
显而易见的解决方案是为每个人创建一个计算列,显示他/她的“今年生日”。很容易从生日中提取月份和日期,添加当前年份,并将整个字符串转换为日期。这样我就可以检索那些“今年生日”在当前日期的 X 天内的人。但是,我有一个人的生日是 2 月 29 日,而且每年都没有 2 月 29 日,所以当我查询或打开表格时,计算列“窒息”并出现以下错误:
将 char 数据类型转换为日期时间数据类型导致日期时间值超出范围。
关于在这种情况下使计算列正常工作的方法的建议,或者使用表中的出生日期查询的替代方法?
解决方法
将您的查询从使用 convert
更改为使用 try_convert
,它不会在不存在的日期出错,而是返回 NULL。如果运行年份不是闰年,这将排除您 2 月 29 日生日的客户。
您的方法不适用于 12 月底,因为年份会发生变化。这是一种不同的方法:
- 将年数添加到日期并让数据库处理闰年。
- 然后进行比较。
所以,第一个的逻辑是:
select dateadd(year,year(getdate()) - year(dob),dob)
然后获取接下来两周的出生日期:
where dateadd(year,dob) >= convert(date,getdate()) and
dateadd(year,dob) < dateadd(14,day,convert(date,getdate())
然而,这仍然不能处理可能是明年的出生日期。因此,要处理年终,也要考虑一下:
where (dateadd(year,getdate()) and
dateadd(year,getdate())
) or
(dateadd(year,1 + year(getdate()) - year(dob),getdate())
)
,
为此 - 您需要计算当前年份的出生日期和下一个出生日期。要计算当前年份的出生日期,我们可以使用一个简单的计算:
dateadd(year,datediff(year,DateOfBirth,CurrentDate),DateOfBirth)
然后 - 我们需要计算下一个出生日期,如果当前年份 DOB 小于 CurrentDate,则只需添加一年:
dateadd(year,iif(CurrentDOB < CurrentDate,1,0),CurrentDOB)
现在 - 只需检查下一个 DOB 是否在范围内。以下是一些示例数据,用于展示如何将这些组合在一起。
--==== Some sample dates of birth - including leap year DOB's
Declare @testData Table (DateOfBirth date);
Insert Into @testData (DateOfBirth)
Values ('1992-01-09'),('2020-02-29'),('1965-09-30'),('1984-02-29');
--==== Test using different dates
Declare @current_date date = '2021-02-28';
--==== Use CROSS APPLY to calculate current year DOB and Next DOB
Select *
From @testData As td
Cross Apply (Values (dateadd(year,td.DateOfBirth,@current_date),td.DateOfBirth))) As y(CurrentDOB)
Cross Apply (Values (dateadd(year,iif(y.CurrentDOB < @current_date,y.CurrentDOB))) As n(NextDOB)
Where n.NextDOB <= dateadd(day,14,@current_date);
如果今天是 2021-02-28,那么将包括 29 日的生日。如果今天是 2021-03-01,那么这些将不会被包括在内,因为它们将被计算为 2022-02-28,而不是在 14 天内。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。