闹心的日历?

这篇博客介绍了农历与阳历的区别,详细讲解了农历的计算方法,包括如何确定闰年、计算农历日期以及农历年份的天数。农历基准与阳历基准的设定、农历年份数组的使用和计算农历月份、日期的步骤也进行了阐述。此外,还提到了天干地支的计算方式以及农历年份天数的求解。
摘要由CSDN通过智能技术生成

calendar

目标

弄懂日历!+ 日历Ui ?

1. 阳历
  • 阳历 每月日期都为固定,把闰年问题解决即可
  • 闰年又分 “普通闰年” 和 “世纪闰年”
    • 普通闰年:公历年份是4的倍数的,且不是100的倍数,为普通闰年(如2004年、2020年就是闰年)。
    • 世纪闰年:公历年份是整百数的,必须是400的倍数才是世纪闰年(如1900年不是世纪闰年,2000年是世纪闰年)。
2. 阴阳历(农历)
2.1. 阴阳历怎么来的?
  • 农历是中国传统历法,也有干支历、华历、夏历、中历等名称。农历是阴阳历的一种,在民间通常被错误地称作阴历。 农历取月相的变化周期即朔望月为月的长度,加入干支历“二十四节气”成分,参考太阳回归年为年的长度,通过设置闰月以使平均历年与回归年相适应。农历是以华历(阴历)为基础,融合阳历成分而成的一种历法。所以我国的农历从严格意义上说不应该叫阴历,而是阴阳合历;详看百度百科

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

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

    例:

    // 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 农历年份数组怎么用?怎么看?
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

分别表示:

xxxxxxxxxxxxxxxxxxxx
20-1716-1212-98-54-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-12月
30,29,30,29,  30,29,29,30,  29,29,30,30


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

0111 1001 0101 0100; 1-4位 0100 转成 十进制为 4 所以是闰4月; 17-20位不存在则为小月29天

2020年全年月份 1-12月 + 闰4月 = 13月
1-12月: 29,30,30,30,        30,29,29,30  29,30,29,30
闰4月:                 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-4位 0110 转成 十进制为 6 所以是闰6月; 17-20位存在则为大月30天

2036年全年月份 1-12月 + 闰6月 = 13月
1-12月: 30,30,29,30, 29,29,       29,29  30,29,30,30
闰6月:                       30,
1-13月: 30,30,29,30, 29,29,  30,  29,29  30,29,30,30
3.2 如何计算农历年份天数

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

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

3.3 天干地支

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

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

生肖与地支公式一样

天干
余数4567890123
地支
余数456789101112123
生肖
余数456789101112123

具体实现

代码片段: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实现公历转农历

天干地支-百度百科

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

闰年-百度百科

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值