问题描述
我正在尝试用普通的 javascript 实现“获取星期几”(Su=0,Mo,...,Sa=6) 函数,并偶然发现了 Tomohiko Sakamoto 算法、Wang 和 Schwerdtfeger。据我了解,这三个应用相同的概念,只是步骤不同,所以为了简单起见,我将在这里只关注 Sakamoto 算法。 我编写了一个简单的测试函数来验证其结果的正确性 - 但在 2004 年 3 月 1 日,它们似乎都出错了,计算结果是星期日(0),而实际上是星期一(1)。
是我弄错了还是我不知道算法有什么特殊的界限?
const DaysInMonth = [
31,// Jan
28,// Feb has 29 in leap years!
31,// Mar
30,// Apr
31,// May
30,// Jun
31,// Jul
31,// Aug
30,// Sep
31,// Okt
30,// Nov
31 // Dec
]
function getWeekDaySakamoto (y,m,d) {
const LookupTable = [0,3,2,5,1,4,6,4]
let year = y
if (m < 3) {
year -= 1
}
return Math.floor((year + year / 4 - year / 100 + year / 400 + LookupTable[m - 1] + d) % 7)
}
let isLeap = false
let wd = 0
let prevWd = -1
// we need to findout where the algo goes wrong
for (let y = 2000; y < 2030; y++) {
isLeap = y % 4 === 0
if (isLeap && y % 100 === 0 && y % 400 !== 0) {
isLeap = false
}
for (let m = 1; m <= 12; m++) {
for (let d = 1; isLeap && m === 2 ? (d <= 29) : (d <= DaysInMonth[m - 1]); d++) {
wd = getWeekDaySakamoto(y,d)
if (prevWd === -1) {
// initialize the value first
prevWd = wd
} else {
if ((wd === 0 && prevWd === 6) ||
(wd === 1 && prevWd === 0) ||
(wd === 2 && prevWd === 1) ||
(wd === 3 && prevWd === 2) ||
(wd === 4 && prevWd === 3) ||
(wd === 5 && prevWd === 4) ||
(wd === 6 && prevWd === 5)) {
console.log(`checked ${y}-${m}-${d} = ${wd}`)
prevWd = wd
} else {
throw new Error(`expected ${y}-${m}-${d} to be a follow up on ${prevWd} but got ${wd}`)
}
}
}
}
}
验证脚本的最终错误消息是 Error: expected 2004-3-1 to be a follow up on 0 but got 0
由于 2004-2-29 是 0
(这是正确的),2004-3-1 应该是 1
但计算为 0
。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)