农历显示

498 阅读2分钟

最近做的一个项目中,需求要求要显示农历,完成之后觉得这个需求的实现挺有趣的,虽然实现没有难度,但是还是想记录一下过程。原型是这样的,重点就在于农历。

image.png

有一个API是可以直接返回农历的,虽然返回的是数字,但是这也让我完成了最重要的一步了。

    new Date().toLocaleString('ja-JP-u-ca-chinese')
    //'壬寅-7-1 15:07:15'

后面就是将数字转化为大写的数字

image.png

但是里面还是有一定的规则的,例如1到10就是初一到初十,11到20就是十一到二十,21到29就是廿一到廿九,30就是三十。还有就是一月是正月,十二月是腊月。既然知道了规则,那么就可以写代码了。

字典

这是一个相当于字典的对象,每一个数字对应的一个值,这样就可以将得到的农历数字转化为大写数字了

      const monthDict = {
        "1": "正",
        "2": "二",
        "3": "三",
        "4": "四",
        "5": "五",
        "6": "六",
        "7": "七",
        "8": "八",
        "9": "九",
        "10": "十",
        "11": "十一",
        "12": "腊",
      }
      const dayDict = {
        "1": "一",
        "2": "二",
        "3": "三",
        "4": "四",
        "5": "五",
        "6": "六",
        "7": "七",
        "8": "八",
        "9": "九",
        "10": "十",
        "0": "十",
      }

根据返回的内容进行分割,就可以得到想要展示的农历部分了。

 new Date().toLocaleString('ja-JP-u-ca-chinese').split(" ")[0].split("-");
//['壬寅', '7', '1']

对于1到12月,就可以直接用字典表的key对应就可以了,而day部分,需要根据规则区分开三部分,就是1到10,11到20,21到29,30四种情况。

      if (dateTimeStr[2] <= 10) {
        day = `初${dayDict[dateTimeStr[2]]}`
      } else if (dateTimeStr[2] > 10 && dateTimeStr[2] <= 20) {
        if (dateTimeStr[2][0] == 1) {
          day = `十${dayDict[dateTimeStr[2][1]]}`
        } else {
          day = `${dayDict[dateTimeStr[2][0]]}${dayDict[dateTimeStr[2][1]]}`
        }
      } else if (dateTimeStr[2] > 20 && dateTimeStr[2] <= 29) {
        day = `廿${dayDict[dateTimeStr[2][1]]}`
      } else {
        day = `${dayDict[dateTimeStr[2][0]]}${dayDict[dateTimeStr[2][1]]}`
      }

最后的结果:

image.png

全部代码:
  calendar() {
      const monthDict = {
        "1": "正",
        "2": "二",
        "3": "三",
        "4": "四",
        "5": "五",
        "6": "六",
        "7": "七",
        "8": "八",
        "9": "九",
        "10": "十",
        "11": "十一",
        "12": "腊",
      }
      const dayDict = {
        "1": "一",
        "2": "二",
        "3": "三",
        "4": "四",
        "5": "五",
        "6": "六",
        "7": "七",
        "8": "八",
        "9": "九",
        "10": "十",
        "0": "十",
      }


      let dateTimeStr = new Date().toLocaleString('ja-JP-u-ca-chinese').split(" ")[0].split("-");
      let day = ""
      if (dateTimeStr[2] <= 10) {
        day = `初${dayDict[dateTimeStr[2]]}`
      } else if (dateTimeStr[2] > 10 && dateTimeStr[2] <= 20) {
        if (dateTimeStr[2][0] == 1) {
          day = `十${dayDict[dateTimeStr[2][1]]}`
        } else {
          day = `${dayDict[dateTimeStr[2][0]]}${dayDict[dateTimeStr[2][1]]}`
        }
      } else if (dateTimeStr[2] > 20 && dateTimeStr[2] <= 29) {
        day = `廿${dayDict[dateTimeStr[2][1]]}`
      } else {
        day = `${dayDict[dateTimeStr[2][0]]}${dayDict[dateTimeStr[2][1]]}`
      }

      return `农历${monthDict[dateTimeStr[1]]}${day}`
    }
总结:

new Date().toLocaleString('ja-JP-u-ca-chinese') 其实参数可以修改为zh-Hans-u-ca-chinese,那这样就可以更快地实现需求了。

  • "ja-JP-u-ca-japanese":在日期和时间格式化中使用日本的日历表示方式,所以 2013 会表示为平成 25。
  • "zh-Hans-u-ca-chinese":在日期和时间格式化中使用中国农历表示方式。

这里有一个非常厉害的库,功能强大

jjonline/calendar.js: 中国农历(阴阳历)和西元阳历即公历互转JavaScript库 (github.com)