首页 > 解决方案 > 计算列日期闰年问题

问题描述

我有一张姓名和相关生日表。我可以通过匹配数据库中的生日和当前日期之间的 MONTH 和 DAY 日期部分来检索今天生日的每个人的姓名。但是,我需要提取未来两周内所有生日的“期待”列表。

显而易见的解决方案是为每个人创建一个计算列,显示他/她的“今年生日”。很容易从生日中提取月份和日期,添加当前年份,并将整个字符串转换为日期。这样我就可以检索那些“今年的生日”在当前日期的 X 天内的人。但是,我有一个人的生日是 2 月 29 日,而且每年都没有 2 月 29 日,所以当我查询或打开表格时,计算列“阻塞”并出现以下错误:

将 char 数据类型转换为 datetime 数据类型会导致 datetime 值超出范围。

关于在这种情况下使计算列正常工作的方法,或者使用表中的出生日期进行查询的替代方法的建议?

标签: sqlsql-servertsqlcalculated-columnsleap-year

解决方案


您的方法在 12 月底将不起作用,因为年份会发生变化。这是一种不同的方法:

  1. 将年数添加到日期并让数据库处理闰年
  2. 然后进行比较。

所以,第一个逻辑是:

select dateadd(year, year(getdate()) - year(dob), dob)

然后在接下来的两周内获得出生日期:

where dateadd(year, year(getdate()) - year(dob), dob) >= convert(date, getdate()) and
      dateadd(year, year(getdate()) - year(dob), dob) < dateadd(14, day, convert(date, getdate())

但是,这仍然不能处理可能是明年的出生日期。因此,要处理年终问题,还要考虑:

where (dateadd(year, year(getdate()) - year(dob), dob) >= convert(date, getdate()) and
       dateadd(year, year(getdate()) - year(dob), dob) < dateadd(14, day, convert(date, getdate())
      ) or
      (dateadd(year, 1 + year(getdate()) - year(dob), dob) >= convert(date, getdate()) and
       dateadd(year, 1 + year(getdate()) - year(dob), dob) < dateadd(14, day, convert(date, getdate())
      )

推荐阅读