与 Sakamoto、Wang、Schwerdtfeger 一起计算星期几是 JS

问题描述

我正在尝试用普通的 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 (将#修改为@)