会员数据库存储了生日,如 1995年5月4日。
需求:今天是2019年3月22日,要查询10天内,或10到30天范围内,或30到60范围内过生日的会员。
问题:数据存储的是日期格式,带年份的,直接比较肯定不行。
思路一:截取月日,如19950504 截取为 ‘0504’,跟当前日期的月日 ‘0322’ 做字符串大小比较
思路二:将所有的生日的年份改为今年,然后做日期比较。
以上两个思路貌似没啥问题,但是不够严谨,比如 12月30日,我要查30天过生日的人,应该包括1月份生日的人,用以上两种方法均查不出。
完美解决思路:
计算出生日那天是每年的第多少天也就是dayOfYear,各种语言都有对应的函数可以获取到dayOfYear 的值。冗余一个字段存储这值也是个不错的选择:dayOfYearBirth。
今天日期的dayOfYear,定义为 dayOfYearToday 。对比这两个值即可。
上一段代码:
const moment = require('moment')
let birthdays = [
'1995-01-01',
'1989-02-21',
'1978-03-04',
'1979-04-10',
'1996-05-20',
'1985-10-11',
'1989-12-01',
'1990-04-23',
'1990-01-12',
]
let dayOfYearToday = moment().dayOfYear()
let start = 10;
let end = 20 // 10到20天内过生日的
birthdays.forEach(birthday=>{
let dayOfYearBirth = moment(birthday).dayOfYear()
if (
//情况一,今年生日还没到
(dayOfYearBirth - dayOfYearToday >= 0
// 减法得到生日还有多少天,是否在start,end范围内
&& dayOfYearBirth - dayOfYearToday <= end
&& dayOfYearBirth - dayOfYearToday>=start)
//另一个情况,今年生日已经过了
|| ((dayOfYearBirth - dayOfYearToday) < 0
//看明年的生日是否在范围内,这里的365不够严谨,可以判断一下闰年情况,变成366
&& (dayOfYearBirth-dayOfYearToday+365)<=end
&& dayOfYearBirth-dayOfYearToday+365>=start)
)
{
console.log(birthday)
}
})
数据库查询也类似,写成sql语句即可。