生日处理
生日的处理在一般的人事处理过程中经常用到,它一般涉及到以下几种处理。
1. 计算年龄
一般的年龄计算都是直接用当前年份减去出生日期的年份,这样得到的年龄并不准确,例如当前日期为2005年3月11日,某个人的出生日期是1978年12月10日,那按年份相减计算出来的年龄是27岁,但此人的实际年龄其实应该是26岁。
要计算准确的年龄,可以这样考虑,将出生日期的月日部分与当前日期的月日部分做比较,如果是大于的情况,则表明今年的生日还没有到,应该将当前日期减去出生日期的结果再减1年,否则直接是两个日期年份相减。但这样做忽略了一个特殊的日期:闰年的2月29号,这个日期出生的人,在平年的时候,应该是2月28号生日,按上面的处理方法恰好是错过了一天,所以完善的解决方法是,将出生日期的年份增加到与当前日期相同,然后再与当前日期比较,如果是大于,则年龄为当前日期减去出生日期的结果再减1年,否则是两个日期直接相减。
处理代码如下(其中,< birthday>是出生日期,<current_date>是当前日期)。
DATEDIFF(Year,<birthday>,<current_date>)
-CASE WHEN DATEADD(Year,DATEDIFF(Year,<birthday>,<current_date>),<birthday>)><current_date>
THEN 1 ELSE 0 END
在实际处理的应用中,要求对年龄进行这样精确计算的比较少,经常做这种计算的一般是工龄(用于员工的奖金及福利待遇处理中)。对工龄的计算,除了要求进行足年计算外,有时还要求进行足月计算。足月计算的处理思路与足年计算处理一样,先计算参加工作的日期与当前日期(或者是指定日期)相差的月份,再将参加工作的日期的年月换算到与当前日期的年月相同,然后与当前日期做比较,如果大于当前日期,则表明未足月,将计算结果减1个月即为实际要求的结果。
处理代码如下(其中<begin_date>是计算的开始日期,<end_date>是计算的结束日期)。
DATEDIFF(Month,<begin_date>,<end_date>)
-CASE WHEN DATEADD(Month,DATEDIFF(Month,<begin_date>,<end_date>),<begin_date>)><end_date>
THEN 1 ELSE 0 END
2. 查询指定时间段内过生日的人员
这个查询需要考虑的是跨年度时间段的查询,及处理特殊日期2月29日的问题。对于2月29日的处理,可以延续计算年龄的处理思路。而对于跨年度的查询,可以把查询条件的开始时间和结束时间分拆为两个或者条件处理,即查询满足如下条件的记录:
¡ 满足出生日期在开始时间到开始时间所在年度最后一天的记录。
¡ 满足结束时间所在年度的第一天到结束时间的记录。
由于生日一年一次,不会跨年,所以也可以把查询处理简化为满足如下条件的记录:
¡ 将出生日期的年份转换到开始日期后,出生日期在开始日期和结束日期的记录。
¡ 将出生日期的年份转换到结束日期后,出生日期在开始日期和结束日期的记录。
下面是查询示例:
--测试数据
DECLARE @t TABLE(ID int,Name varchar(10),Birthday datetime)
INSERT @t SELECT 1,'aa','1999-01-01'
UNION ALL SELECT 2,'bb','1996-02-29'
UNION ALL SELECT 3,'bb','1934-03-01'
UNION ALL SELECT 4,'bb','1966-04-01'
UNION ALL SELECT 5,'bb','1997-05-01'
UNION ALL SELECT 6,'bb','1922-11-21'
UNION ALL SELECT 7,'bb','1989-12-11'
DECLARE @dt1 datetime,@dt2 datetime
--查询 2003-12-05 至 2004-02-28 生日的记录
SELECT @dt1='2003-12-05',@dt2='2004-02-28'
SELECT * FROM @t
WHERE DATEADD(Year,DATEDIFF(Year,Birthday,@dt1),Birthday)
BETWEEN @dt1 AND @dt2
OR DATEADD(Year,DATEDIFF(Year,Birthday,@dt2),Birthday)
BETWEEN @dt1 AND @dt2
/*--结果
ID Name Birthday
---------------- ---------------- --------------------------
1 aa 1999-01-01 00:00:00.000
7 bb 1989-12-11 00:00:00.000
--*/
--查询 2003-12-05 至 2006-02-28 生日的记录
SET @dt2='2006-02-28'
SELECT * FROM @t
WHERE DATEADD(Year,DATEDIFF(Year,Birthday,@dt1),Birthday)
BETWEEN @dt1 AND @dt2
OR DATEADD(Year,DATEDIFF(Year,Birthday,@dt2),Birthday)
BETWEEN @dt1 AND @dt2
/*--查询结果
ID Name Birthday
---------------- ----------------- --------------------------
1 aa 1999-01-01 00:00:00.000
2 bb 1996-02-29 00:00:00.000
7 bb 1989-12-11 00:00:00.000
--*/