为了账号安全,请及时绑定邮箱和手机立即绑定

看到百度的那个万年历了吗,咱们也来做一个吧。

       原创声明,转载请注明出处。

        咱先来看看具体效果吧,

        https://dorsey.oss-cn-hangzhou.aliyuncs.com/PC/module/module/calendar.html

        细心的你会发现好像只有这一天是初几,没有月份,嗯是的,因为现在很晚了,我好困了,想睡觉。 

       这里有字数限制。。。要看代码呢??去这里吧:https://www.imooc.com/article/43085

首先呢,百度日历里面的那些天干啊,地支啊,今天忌啥宜啥,这些是需要数据的,天干地支还好了,忌啥宜啥这个咱就不写了,这需要数据支撑,咱没必要。那我们的万年历是怎样的呢?大概就是农历+节日+节气吧。另外呢,这个年历本身相对就比较复杂,代码也较多,整篇文章会比较长,有耐心的请继续看下去哈。

        先从简单的纯阳历开始哈:

        我们知道,js给我们提供了日期函数这么个非常好用的东西,我们从这个日期函数最基本可以知道当下时间,实际上它的根据是什么呢?是世界时(后面会涉及到),好了不扯,一个个来。

        首先呢,咱先来创建一些html结构:

https://img1.sycdn.imooc.com//5b4032ec0001745012880528.jpg

        其次呢,看看下面这段代码:

https://img1.sycdn.imooc.com//5b40313e0001c37b07960136.jpg

        这个就是一些基本的获取办法,也就是我们能知道的其实也就这么多。那我们怎么根据这些一步步推算出我们想要的整个万年历?

        下面是我的思路:

        ①:看到我们创建的表格了吧?是不是一个7*6的表格(tbody),再加个定死的星期(thead)?

            另外呢,看看22号对应的日历,是不是很尴尬的变成一个十十?嗯,咱后续来说哈。

https://img1.sycdn.imooc.com//5b403d5d0001004907280498.jpg

        ②:表格结构是好了的,我们只需要对应着填数据,首先7*6这个表格我们先吧1-42这个数据一一填进去,得到一个表格是这样的:

https://img1.sycdn.imooc.com//5b40444c00015ec005810362.jpg

        ③:那接下来怎么把这个月的1号显示在该月对应的星期上呢?(比如1号是星期三,我们得在星期三那里写入1号对吧?),如果说,这个月1号是星期三,那我直接把星期三对应的那个4号减去3不就可以了?全部都减去3对吧?你说减之后有小于0的,也有大于这个月天数的,对吧?咱让小于0大于这个月天数的的都隐藏了,是不是就可以了??答案是是的。当然,咱不隐藏,咱让他们变灰色,但是呢,灰色还是负数跟比较大的数啊,嗯,咱这样想,如果小于0的,是不是就是上个月的后面几天?如果大于0的,是不是就直接1号重新开始?我列一列这个数据变换过程哈。

        一开始:1~42;

        接着:-x~42-x;

        接着:小于0的,-x~0      上个月的天数倒数,同时变灰色

        接着:大于这个月天数的,month~(42-x)        1 ~  42-x~month,同时变灰色

        最后呢:处于0~month这个范围的就依次填入表格就好了。

        看看下面这个哈:

https://img1.sycdn.imooc.com//5b4051850001c37a09370279.jpg

        但是呢,又有问题了,这个月第一天是星期几?咱怎么知道啊?这个js给我们提供了,看下面:

https://img1.sycdn.imooc.com//5b40476f0001f57906510090.jpg

        第一天搞定了,可是还是有问题啊,最后一天我不知道哇,我那知道这个月是哪个月,总天数有多少,你让我去减这个月的总天数啥的不是扯吗?不不不,不扯,既然不知道,那来获取下不就可以?

        首先,我们先普及下常识,阳历的年一般是365天,闰年加一天,月份呢,除了2月份在闰年时加多一天是29天之外,其他月份的天数都是不变的,也就是这样:

        1,3,4,5,6,7,8,9,10,11,12:月份的天数是固定的,至于哪个是31天哪个是30天请握拳数你的拳头。

        2月份:特殊,平常年是28天,闰年是29天,这是不是特别有规律?

        然后呢?月知道了,那我咋知道这一年是不是闰年啊?

        闰年的话,我们大家都知道对吧,无非是能被4整除的且这一年不是整百年(如2100)的,或者是整百年且可以被400整除的就是闰年。

        看下哈:

https://img1.sycdn.imooc.com//5b404a3200017c2907400121.jpg

        ④:这样是不是万年历的一页就出来了,对吧?既然有一页,那肯定得有无限页,起码看起来像是无限页对吧?得有上个月下个月,上年下年,首先因为我们进来的时候显示的时间就是当前时间,年月日都有,那你上年上月就减1,下年或下月就加1呗。只不过呢,当月份到12之后记得变成1。

https://img1.sycdn.imooc.com//5b404b060001b05104930442.jpg

        看下面的代码好像是0-11啊,没错,是0-11,这是js时间函数决定的。咱显示的时候修一修就OK了比如说这样:

https://img1.sycdn.imooc.com//5b404c010001461410250054.jpg

        ⑤:年月日星期都有了,而且也能上下月上下年了,其实纯的年历就基本完了,可能一些细节上微调一下,比如你鼠标在日期滑动动态修改显示的日期,星期啥的这就不说了比较简单。


        好了,进入咱的重点哈,农历。

        首先,农历这个东西,我们是没有规律可循的,因为农历是阴历,用来指导农业生产,它是根据月亮围绕地球公转一周算一个周期来算的,而阳历是根据地球围绕太阳一周为一周期来算,所以呢,实际上,农历跟阳历是没啥对应关系的,毕竟天体公转嘛,而天文学家呢,为了让这两个历有稍微比较合理的并行关系,不至于出现农历的春节出现在阳历的9月份,那就特别奇怪了,所以有一系列的调整方式,同时又不影响农业生产指导。(比如农历的闰年是13个月,就是用来调整农历周期的),至于具体如何计算,很复杂,反正最终这两个核算起来相差无几,而这样,农历就无规律可循了,必须依赖天文学家给出的农历数据(比如这个数据会跟你说,今年是不是闰年,是闰在哪个月份,且其他月份有多少个29天的,多少个30天的等等),这样根据天文学家通过天体观测做出的农历数据生成的农历,对农业的生产具有相当大的指导作用。(你见过“秋收”节气的时候谁在种水稻的?)

        既然是这样,那无规律可循,咱只能去解析目前的农历数据了。(现有的农历数据是从1900~2100两百年的时间)

        先来看看农历源数据是怎样的?又是什么意思,每个部分又代表着怎样的功能呢?

https://img1.sycdn.imooc.com//5b406f1c0001b6fe09250579.jpg

比如说:1900的数据是0x04bd8,把它拆分成3部分:(前面的0x是C语言的一种写法,后续发展起来的语言也沿用这种写法(当然啦,也包括js),代表16进制可以不用管)

①:0     :只会出现0跟1两种值,代表如果是闰年,多出的那个月是大月还是小月,1代表大月(30), 0代表小月(29)天数。

②:4bd:需要变成2进制数:0100    1011    1101    从左到右分别代表农历非闰月的1~12月的天数。1为30,0为29。

③:8     :代表这一年闰月是闰几月,比如这里是闰8月。如果这一年没有闰月则为0

那怎么算出农历呢?我的思路是这样,有什么更好的思路欢迎指教。

①:我们从农历数据可以知道这一年里的所以月份的天数。包括有无闰月

②:1900年1月31日为农历正月初一。

③:我们只要计算出当前或者任意时间同1900年1月31日的偏移值,就可以知道是农历初几了。

逻辑看起来简单,等你写了之后,你会发现有很多坑。这里的话呢,我在代码的注释里有说明了。

④:上面的几步是最基本的,但是呢,农历是没有任何规律可循的,只能依赖查表,所以呢,直接计算每一天同1900年1月31日的偏移值无疑是难上加难,不过呢,我们可以这样,先计算出任意一年1月1号(指阳历)的农历值(实际上是偏移值),再根据每一年里的所有月份,逐步去推算出每一个月的第一天的偏移值,每个月的第一天知道了,整个月也就知道了。

//原创首发于慕课网














点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
1.3万
获赞与收藏
1519

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消