找出所有回文日?交给计算机吧!
December 02, 2021

今天大家是不是被 20211202 这个回文日刷屏了呢?朋友圈有人说,下次遇到这种类似的回文日,需要再等九年。

好奇宝宝肯定会问,回文日究竟有多稀少呢?

这种任务肯定交给计算机最合适了!

语言我们选用 JavaScript!

// 枚举回文数,然后判断是否是一个合法的日期 📅

// 1000-01-01
// 9999-12-31

const numberOfDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

function isLeapYear(year) {
    if (year % 100 === 0 && year % 400 == 0) {
        return true;
    }
    return year % 4 === 0;
}

// 假设我们已经枚举出了一个回文数,判断是否合法,只处理 8 位数
function validDateNumber(dateNumber) {
    const dateString = dateNumber.toString();
    const year = parseInt(dateString.slice(0, 4), 10);
    const month = parseInt(dateString.slice(4, 6), 10);
    const day = parseInt(dateString.slice(6, 8), 10);
    if (month === 0 || month > 12) {
        return false;
    }
    if (month === 2) {
        if (isLeapYear(year) && day <= 29) {
            return true;
        }
        return day <= 28;
    }
    return day <= numberOfDays[month - 1];
}

// 枚举所有的回文 8 位数
function enumerate() {
    let count = 0;
    for (let base = 1000; base < 10000; base++) {
        let parlindrome = base;
        let temp = base;
        while (temp != 0) {
            parlindrom = parlindrome * 10 + temp % 10;
            temp = Math.floor(temp / 10);
        }
        if (validDateNumber(parlindrome)) {
            console.log(parlindrom);
            count++;
        }
    }
    console.log(count);
}

enumerate();

打开你的浏览器,我的是 Google Chrome,然后按 Fn + 12 就可以进入开发者界面,在这里找到 console。然后把上面这段代码输入进去,就可以打印出从公元 1000 年到 9999 年所有的回文日啦!总共数量是 331 个。

2000 年之前最近的一个回文日是 1380 年 8 月 31 日,而进入 2000 年后回文日以几乎 10 年一遇的规律出现,分别是 2001 年 10 月 2 日、2010 年 1 月 2 日、2021 年 12 月 2 日(今天!)、2030 年 3 月 2 日、2040 年 4 月 2 日,依次类推。

所以,回文日是一个属于我们这个时代的 10 年一遇的纪念日。

以人生为界限,我们能遇到的回文日只有数个,顶多十数个。

它对称、美观、奇妙、稀少。但这些其实不过是我们人类强行给时间赋予的标记。

然而,如果不被赋予意义,时间只不过是那无垠沙漠中一粒粒沙石。积累、建造,持之以恒地给时间赋予意义,以一个个回文日为阶段,最终我们终将构建出瑰丽的世界。

下一个回文日是 9 年后的 2030 年 3 月 2 日,那个时候我已经步入了我的三十岁。希望从今天起走过的这 9 年,可以不辜负这个时代。