看到百度的那个万年历了吗,咱们也来做一个吧。
原创声明,转载请注明出处。
咱先来看看具体效果吧,
https://dorsey.oss-cn-hangzhou.aliyuncs.com/PC/module/module/calendar.html
细心的你会发现好像只有这一天是初几,没有月份,嗯是的,因为现在很晚了,我好困了,想睡觉。
这里有字数限制。。。要看代码呢??去这里吧:https://www.imooc.com/article/43085
首先呢,百度日历里面的那些天干啊,地支啊,今天忌啥宜啥,这些是需要数据的,天干地支还好了,忌啥宜啥这个咱就不写了,这需要数据支撑,咱没必要。那我们的万年历是怎样的呢?大概就是农历+节日+节气吧。另外呢,这个年历本身相对就比较复杂,代码也较多,整篇文章会比较长,有耐心的请继续看下去哈。
先从简单的纯阳历开始哈:
我们知道,js给我们提供了日期函数这么个非常好用的东西,我们从这个日期函数最基本可以知道当下时间,实际上它的根据是什么呢?是世界时(后面会涉及到),好了不扯,一个个来。
首先呢,咱先来创建一些html结构:
其次呢,看看下面这段代码:
这个就是一些基本的获取办法,也就是我们能知道的其实也就这么多。那我们怎么根据这些一步步推算出我们想要的整个万年历?
下面是我的思路:
①:看到我们创建的表格了吧?是不是一个7*6的表格(tbody),再加个定死的星期(thead)?
另外呢,看看22号对应的日历,是不是很尴尬的变成一个十十?嗯,咱后续来说哈。
②:表格结构是好了的,我们只需要对应着填数据,首先7*6这个表格我们先吧1-42这个数据一一填进去,得到一个表格是这样的:
③:那接下来怎么把这个月的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这个范围的就依次填入表格就好了。
看看下面这个哈:
但是呢,又有问题了,这个月第一天是星期几?咱怎么知道啊?这个js给我们提供了,看下面:
第一天搞定了,可是还是有问题啊,最后一天我不知道哇,我那知道这个月是哪个月,总天数有多少,你让我去减这个月的总天数啥的不是扯吗?不不不,不扯,既然不知道,那来获取下不就可以?
首先,我们先普及下常识,阳历的年一般是365天,闰年加一天,月份呢,除了2月份在闰年时加多一天是29天之外,其他月份的天数都是不变的,也就是这样:
1,3,4,5,6,7,8,9,10,11,12:月份的天数是固定的,至于哪个是31天哪个是30天请握拳数你的拳头。
2月份:特殊,平常年是28天,闰年是29天,这是不是特别有规律?
然后呢?月知道了,那我咋知道这一年是不是闰年啊?
闰年的话,我们大家都知道对吧,无非是能被4整除的且这一年不是整百年(如2100)的,或者是整百年且可以被400整除的就是闰年。
看下哈:
④:这样是不是万年历的一页就出来了,对吧?既然有一页,那肯定得有无限页,起码看起来像是无限页对吧?得有上个月下个月,上年下年,首先因为我们进来的时候显示的时间就是当前时间,年月日都有,那你上年上月就减1,下年或下月就加1呗。只不过呢,当月份到12之后记得变成1。
看下面的代码好像是0-11啊,没错,是0-11,这是js时间函数决定的。咱显示的时候修一修就OK了比如说这样:
⑤:年月日星期都有了,而且也能上下月上下年了,其实纯的年历就基本完了,可能一些细节上微调一下,比如你鼠标在日期滑动动态修改显示的日期,星期啥的这就不说了比较简单。
好了,进入咱的重点哈,农历。
首先,农历这个东西,我们是没有规律可循的,因为农历是阴历,用来指导农业生产,它是根据月亮围绕地球公转一周算一个周期来算的,而阳历是根据地球围绕太阳一周为一周期来算,所以呢,实际上,农历跟阳历是没啥对应关系的,毕竟天体公转嘛,而天文学家呢,为了让这两个历有稍微比较合理的并行关系,不至于出现农历的春节出现在阳历的9月份,那就特别奇怪了,所以有一系列的调整方式,同时又不影响农业生产指导。(比如农历的闰年是13个月,就是用来调整农历周期的),至于具体如何计算,很复杂,反正最终这两个核算起来相差无几,而这样,农历就无规律可循了,必须依赖天文学家给出的农历数据(比如这个数据会跟你说,今年是不是闰年,是闰在哪个月份,且其他月份有多少个29天的,多少个30天的等等),这样根据天文学家通过天体观测做出的农历数据生成的农历,对农业的生产具有相当大的指导作用。(你见过“秋收”节气的时候谁在种水稻的?)
既然是这样,那无规律可循,咱只能去解析目前的农历数据了。(现有的农历数据是从1900~2100两百年的时间)
先来看看农历源数据是怎样的?又是什么意思,每个部分又代表着怎样的功能呢?
比如说: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号(指阳历)的农历值(实际上是偏移值),再根据每一年里的所有月份,逐步去推算出每一个月的第一天的偏移值,每个月的第一天知道了,整个月也就知道了。
//原创首发于慕课网
共同学习,写下你的评论
评论加载中...
作者其他优质文章