评论

闹心的日历?

阳历 + 农历UI;v0.7

目标

弄懂日历!+ 日历Ui ?

1. 阳历

  • 阳历 每月日期都为固定,把闰年问题解决即可
  • 闰年又分 “普通闰年” 和 “世纪闰年”
    • 普通闰年:公历年份是4的倍数的,且不是100的倍数,为普通闰年(如2004年、2020年就是闰年)。
    • 世纪闰年:公历年份是整百数的,必须是400的倍数才是世纪闰年(如1900年不是世纪闰年,2000年是世纪闰年)。

2. 阴阳历(农历)

2.1. 阴阳历怎么来的?
  • 农历是中国传统历法,也有干支历、华历、夏历、中历等名称。农历是阴阳历的一种,在民间通常被错误地称作阴历。 农历取月相的变化周期即朔望月为月的长度,加入干支历“二十四节气”成分,参考太阳回归年为年的长度,通过设置闰月以使平均历年与回归年相适应。农历是以华历(阴历)为基础,融合阳历成分而成的一种历法。所以我国的农历从严格意义上说不应该叫阴历,而是阴阳合历;详看百度百科

  • 所以平常我们说的阴历其实是阴阳历或农历。 那阴阳历是怎么来的?主要是天文台夜观天象得来的,并非向阳历那般有固定日期。现有农历数据只有1949年-2100年 200年的数据

    Ps: 在中国科学院紫金山天文台官网上没找到数据源,如有大佬熟知,望告知,解小弟疑惑;

    例:

    // 1949年 - 2100年 农历年份
    
    const lunarYearArr = [
      0x0b557, //1949
      0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
      .....,
      0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099
      0x0d520 //2100
    ]
    

    关于这些年份的解释- 3.1 农历年份数组怎么用?怎么看?

2.2 如何计算农历日期

(输入的阳历日期 − 阳历基准 + 1)=(输出的农历日期 − 农历基准 + 1)= 相差天数

  • 先计算输入的阳历日期与阳历基准之间相差天数,计算出的相差天数是固定的。

  • 之后在根据 相差天数反推出农历日期

2.3 确认阳历基准与农历基准

基准可以是日历上的任意一天,但是阳历基准和农历基准必须是同一天。 要注意的是设置基准后,基准以前的日期将计算错误,只能计算基准以后的。

基准年份要与农历年份数组第一个值相对应,要不然也会出现计算误差。

例:

const solarYear = 2019 // 阳历年份基准

const lunarYearArr = [
    0x0a930, //2019
    ......,
    0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0, 0x0d150, 0x0f252, //2090-2099
    0x0d520 //2100
] // 农历年份 数组,第一个必须为 2019; 也就是阳历年份基准

2.4 计算农历年份
  • 使用 相差天数 依次减去 农历数组中每一年的天数
  • 当 相差天数 <= 0 时 即确认当前农历年份
2.5 计算农历月份
  • 确认农历年份后,最后一次减去的年份 + 相差天数 = 农历年份的天数

  • 使用 农历年份的天数 依次减去 农历年份中的每月的天数

  • 当 农历年份的天数 <= 0 时 即确认当前农历月份

2.6 计算农历日份
  • 确认农历月份后,最后一次减去的月份 + 农历年份的天数 = 当前农历日份

3. 阴阳历(农历)扩展

3.1 <span id=“threeone”>农历年份数组怎么用?怎么看?</span>
const lunarYearArr = [
    0x0b557, //1949
    0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, //1950-1959
    .....,
]

将 0x0b557 除 0x 外的 0b557(16进制) 转为 二进制,会得到以下数据:

0000 1011 0101 0101 0111

分别表示:

xxxx xxxx xxxx xxxx xxxx
20-17 16-12 12-9 8-5 4-1

1-4位: 表示是否为闰年,是 则为闰年的月份; 否 为 0;

5-16位: 除闰年外的正常月份,1为 30天大月;0为 29天小月;(1月-12月的对应顺序为16位-5位)

17-20位:表示闰月为 大月还是小月,有闰月时才有意义

例:

>> 无闰月版
2019年的 16进制为0x0a930 二进制为 1010100100110000

1010 1001 0011 0000; 可以看到 17-20位是没有的,因为2019年没有闰月

2019年全年月份1-1230,29,30,29,  30,29,29,30,  29,29,30,30


------
>> 有闰月-小月版
2020年的 16进制为0x07954 二进制为111100101010100 //这里的二进制只有15位, 手动添0,添置到16位

0111 1001 0101 0100; 1-40100 转成 十进制为 4 所以是闰4月; 17-20位不存在则为小月292020年全年月份 1-12月 + 闰4月 = 131-12月: 29,30,30,30,        30,29,29,30  29,30,29,304月:                 29,
1-13月: 29,30,30,30,   29,  30,29,29,30  29,30,29,30


------
>> 有闰月-大月版
2036年的 16进制为0x1d0b6 二进制为11101000010110110 //这里的二进制只有17位,手动添0,添置到20位

0001 1101 0000 1011 0110; 1-40110 转成 十进制为 6 所以是闰6月; 17-20位存在则为大月302036年全年月份 1-12月 + 闰6月 = 131-12月: 30,30,29,30, 29,29,       29,29  30,29,30,306月:                       30,
1-13月: 30,30,29,30, 29,29,  30,  29,29  30,29,30,30
3.2 如何计算农历年份天数

看完3.1 农历年份数组怎么用?怎么看?之后就应该可以明白

知道 每月天数后相加即可 得出一年总天数; 如当前年有闰月,别忘了加闰月月份。

3.3 天干地支

天干=(公历年份)/10,所得余数

地支=(公历年份)/12,所得余数

生肖与地支公式一样

天干
余数 4 5 6 7 8 9 0 1 2 3
地支
余数 4 5 6 7 8 9 10 11 12 1 2 3
生肖
余数 4 5 6 7 8 9 10 11 12 1 2 3

具体实现

代码片段:https://developers.weixin.qq.com/s/3NhBSfmw7RmE
github: https://github.com/angxuejian/moto.wxui/tree/main/UI/calendar

参考文献

limengwe-关于日历实现代码里0x04bd8, 0x04ae0, 0x0a570的解释

xm2by-日历的公历转农历

xm2by-原生js实现公历转农历

天干地支-百度百科

本文农历知识均为以上文章提供

闰年-百度百科

最后一次编辑于  2020-11-30  
点赞 0
收藏
评论
登录 后发表内容