昨天在《枕边算法书》看到一个撩妹技巧:“美丽的女士,请您随便说一个年份,我会猜出当年的情人节是星期几”。那这哥们是如何快速的算出的呢?书中提到了
康威的末日算法
,其原理就是设立一个基点,根据星期以7为循环的原理和对闰年的考虑。
为了获取某天是星期几,用这个末日算法还是很麻烦。在JavaScript中有一个可爱的 getDay()
,它可以获取我们想要的结果。例如:
// 获取今天星期几
new Date().getDay();
// => 得到0 ~ 6 的一个数值,代表星期日 ~周期六
// 获取某天星期几
new Date('2018/6/3').getDay();
// => 0 (星期日)
⚠️注意:'2018-6-3' 这种格式在ios下会有兼容性问题
那问题来了,如果不用getDay,我们如何获取某天是星期几?
答案是:通过基姆拉尔森计算公式
基姆拉尔森计算公式
W= (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400) mod 7
w的值范围0~6(星期一~星期日)注意/是整除
在公式中d表示日期中的日数, m表示月份数, y表示年数。
注意: 在公式中有个与其他公式不同的地方:
把一月和二月看成是上一年的十三月和十四月, 例: 如果是2018/1/1 则换算成: 2017/13/1 来代入公式计算
下面来看下代码:
function getWeek(y, m, d) {
const startWeek = 1;
if (m < 3) {
m += 12;
--y;
}
return (d + startWeek + 2 * m + Math.floor(3 * (m + 1) / 5) + y + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400)) % 7;
}
function getWeekText(y, m, d) {
const aWeekTxt = ['周日', '星期一', '星期二', '星期三', '星期四', '星期五', '周六']
return aWeekTxt[getWeek(y, m, d)];
}
在基姆拉尔森中/
是整除,所以在JavaScript中我们要用Math.floor
进行取整数的处理,不然计算结果就会有问题。在getWeek
中定义了一个startWeek=1
的常量,在原公式返回的结果是0~6代表周一到周日,而在JavaScript:0代表周日,我们通过d+1
使返回的结果和getDay
的结果一样,当然weekStart
也可以定义成你想要的星期。