JavaScript实现有农历和节气节假日的日历

运行效果:

源代码:

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5     <title>带农历的日历</title>
  6 
  7 <body onload=initial()>
  8     <center>
  9         <form name=CLD>
 10             <table>
 11                 <tr>
 12                     <td align=middle>
 13                         <table border=1 cellpadding="0" cellspacing="0" bordercolordark="#FFFFFF" bordercolor="#ffffff"
 14                             bordercolorlight="#EEEEEE">
 15                             <tr bgcolor="#006600">
 16                                 <td colspan=7>
 17                                     <font color=#ffffff style="FONT-SIZE: 9pt">公历
 18                                         <select name=SY onchange=changeCld() style="FONT-SIZE: 9pt">
 19                                             <script language="JavaScript">
 20                                                 for (i = 1900; i < 2050; i++) document.write('<option>' + i);
 21                                             </script>
 22                                         </select> 年 <select name=SM onchange=changeCld() style="FONT-SIZE: 9pt">
 23                                             <script language="JavaScript">
 24                                                 for (i = 1; i < 13; i++) document.write('<option>' + i);
 25                                             </script>
 26                                         </select> 月 </font>
 27                                     <font color=#ffffff face=宋体 id=GZ style="FONT-SIZE: 12pt"></font><BR>
 28                                 </td>
 29                             </tr>
 30                             <tr align=middle bgColor=#e0e0e0>
 31                                 <td width=54 style="font-size:9pt; padding:5pt;">日</td>
 32                                 <td width=54 style="font-size:9pt ">一</td>
 33                                 <td width=54 style="font-size:9pt ">二</td>
 34                                 <td width=54 style="font-size:9pt ">三</td>
 35                                 <td width=54 style="font-size:9pt ">四</td>
 36                                 <td width=54 style="font-size:9pt ">五</td>
 37                                 <td width=54 style="font-size:9pt ">六</td>
 38                             </tr>
 39                             <script type="text/javascript">
 40                                 var gNum;
 41                                 for (i = 0; i < 6; i++) {
 42                                     document.write('<tr align=center>');
 43                                     for (j = 0; j < 7; j++) {
 44                                         gNum = i * 7 + j;
 45                                         document.write('<td id="GD' + gNum + '"><font id="SD' + gNum + '" size=2 face="Arial Black"');
 46                                         if (j == 0) {
 47                                             document.write('color=red');
 48                                         }
 49                                         if (j == 6) {
 50                                             document.write('color=#000080');
 51                                         }
 52                                         document.write(' title=""></font><br><font id="LD' + gNum + '" size=2 style="font-size:9pt"> </font></td>');
 53                                     }
 54                                     document.write('</tr>');
 55                                 }
 56                             </script>
 57                         </table>
 58                     </td>
 59                 </tr>
 60             </table>
 61         </form>
 62     </center>
 63 
 64     <script type="text/javascript">
 65         var lunarInfo = new Array(
 66             0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
 67             0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
 68             0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
 69             0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
 70             0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
 71             0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
 72             0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
 73             0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
 74             0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
 75             0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
 76             0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
 77             0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
 78             0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
 79             0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
 80             0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0)
 81 
 82         var solarMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
 83         var Animals = new Array("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪");
 84         var solarTerm = new Array("小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至");
 85         var sTermInfo = new Array(0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758);
 86         var nStr1 = new Array('日', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十');
 87         var nStr2 = new Array('初', '十', '廿', '卅');
 88         //公历节日
 89         var sFtv = new Array(
 90             "0101 元旦",
 91             "0214 情人节",
 92             "0308 妇女节",
 93             "0312 植树节",
 94             "0315 消费者权益日",
 95             "0401 愚人节",
 96             "0501 劳动节",
 97             "0504 青年节",
 98             "0512 护士节",
 99             "0601 儿童节",
100             "0701 建党节",
101             "0801 建军节",
102             "0910 教师节",
103             "0928 孔子诞辰",
104             "1001 国庆节",
105             "1006 老人节",
106             "1024 联合国日",
107             "1224 平安夜",
108             "1225 圣诞节")
109         //农历节日
110         var lFtv = new Array(
111             "0101 春节",
112             "0115 元宵节",
113             "0505 端午节",
114             "0707 七夕情人节",
115             "0715 中元节",
116             "0815 中秋节",
117             "0909 重阳节",
118             "1208 腊八节",
119             "1224 小年")
120         //返回农历y年的总天数
121         function lYearDays(y) {
122             var i, sum = 348;
123             for (i = 0x8000; i > 0x8; i >>= 1)sum += (lunarInfo[y - 1900] & i) ? 1 : 0;
124             return (sum + leapDays(y));
125         }
126         //返回农历y年闰月的天数
127         function leapDays(y) {
128             if (leapMonth(y)) return ((lunarInfo[y - 1900] & 0x10000) ? 30 : 29);
129             else return (0);
130         }
131         //判断y年的农历中那个月是闰月,不是闰月返回0
132         function leapMonth(y) {
133             return (lunarInfo[y - 1900] & 0xf);
134         }
135         //返回农历y年m月的总天数
136         function monthDays(y, m) {
137             return ((lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29);
138         }
139         //算出当前月第一天的农历日期和当前农历日期下一个月农历的第一天日期
140         function Dianaday(objDate) {
141             var i, leap = 0, temp = 0;
142             var baseDate = new Date(1900, 0, 31);
143             var offset = (objDate - baseDate) / 86400000;
144             this.dayCyl = offset + 40;
145             this.monCyl = 14;
146             for (i = 1900; i < 2050 && offset > 0; i++) {
147                 temp = lYearDays(i)
148                 offset -= temp;
149                 this.monCyl += 12;
150             }
151             if (offset < 0) {
152                 offset += temp;
153                 i--;
154                 this.monCyl -= 12;
155             }
156             this.year = i;
157             this.yearCyl = i - 1864;
158             leap = leapMonth(i); //闰哪个月
159             this.isLeap = false;
160             for (i = 1; i < 13 && offset > 0; i++) {
161                 if (leap > 0 && i == (leap + 1) && this.isLeap == false) {    //闰月
162                     --i; this.isLeap = true; temp = leapDays(this.year);
163                 }
164                 else {
165                     temp = monthDays(this.year, i);
166                 }
167                 if (this.isLeap == true && i == (leap + 1)) this.isLeap = false;    //解除闰月
168                 offset -= temp;
169                 if (this.isLeap == false) this.monCyl++;
170             }
171             if (offset == 0 && leap > 0 && i == leap + 1)
172                 if (this.isLeap) { this.isLeap = false; }
173                 else { this.isLeap = true; --i; --this.monCyl; }
174             if (offset < 0) { offset += temp; --i; --this.monCyl; }
175             this.month = i;
176             this.day = offset + 1;
177         }
178         //返回公历y年m+1月的天数
179         function solarDays(y, m) {
180             if (m == 1)
181                 return (((y % 4 == 0) && (y % 100 != 0) || (y % 400 == 0)) ? 29 : 28);
182             else
183                 return (solarMonth[m]);
184         }
185         //记录公历和农历某天的日期
186         function calElement(sYear, sMonth, sDay, week, lYear, lMonth, lDay, isLeap) {
187             this.isToday = false;
188             //公历
189             this.sYear = sYear;
190             this.sMonth = sMonth;
191             this.sDay = sDay;
192             this.week = week;
193             //农历
194             this.lYear = lYear;
195             this.lMonth = lMonth;
196             this.lDay = lDay;
197             this.isLeap = isLeap;
198             //节日记录
199             this.lunarFestival = ''; //农历节日
200             this.solarFestival = ''; //公历节日
201             this.solarTerms = ''; //节气
202         }
203         //返回某年的第n个节气为几日(从0小寒起算)
204         function sTerm(y, n) {
205             var offDate = new Date((31556925974.7 * (y - 1900) + sTermInfo[n] * 60000) + Date.UTC(1900, 0, 6, 2, 5));
206             return (offDate.getUTCDate())
207         }
208         //保存y年m+1月的相关信息
209         var fat = mat = 9;
210         var eve = 0;
211         function calendar(y, m) {
212             fat = mat = 0;
213             var sDObj, lDObj, lY, lM, lD = 1, lL, lX = 0, tmp1, tmp2;
214             var lDPOS = new Array(3);
215             var n = 0;
216             var firstLM = 0;
217             sDObj = new Date(y, m, 1);    //当月第一天的日期
218             this.length = solarDays(y, m);    //公历当月天数
219             this.firstWeek = sDObj.getDay();    //公历当月1日星期几
220             if ((m + 1) == 5) { fat = sDObj.getDay() }
221             if ((m + 1) == 6) { mat = sDObj.getDay() }
222             for (var i = 0; i < this.length; i++) {
223                 if (lD > lX) {
224                     sDObj = new Date(y, m, i + 1);    //当月第一天的日期
225                     lDObj = new Dianaday(sDObj);     //农历
226                     lY = lDObj.year;           //农历年
227                     lM = lDObj.month;          //农历月
228                     lD = lDObj.day;            //农历日
229                     lL = lDObj.isLeap;         //农历是否闰月
230                     lX = lL ? leapDays(lY) : monthDays(lY, lM); //农历当月最后一天
231                     if (lM == 12) { eve = lX }
232                     if (n == 0) firstLM = lM;
233                     lDPOS[n++] = i - lD + 1;
234                 }
235                 this[i] = new calElement(y, m + 1, i + 1, nStr1[(i + this.firstWeek) % 7], lY, lM, lD++, lL);
236                 if ((i + this.firstWeek) % 7 == 0) {
237                     this[i].color = 'red';  //周日颜色
238                 }
239             }
240             //节气
241             tmp1 = sTerm(y, m * 2) - 1;
242             tmp2 = sTerm(y, m * 2 + 1) - 1;
243             this[tmp1].solarTerms = solarTerm[m * 2];
244             this[tmp2].solarTerms = solarTerm[m * 2 + 1];
245             if ((this.firstWeek + 12) % 7 == 5) {//黑色星期五
246                 this[12].solarFestival += '黑色星期五';
247             }
248             if (y == tY && m == tM) {
249                 this[tD - 1].isToday = true;    //今日
250             }
251         }
252         //用中文显示农历的日期
253         function cDay(d) {
254             var s;
255             switch (d) {
256                 case 10:
257                     s = '初十';
258                     break;
259                 case 20:
260                     s = '二十';
261                     break;
262                 case 30:
263                     s = '三十';
264                     break;
265                 default:
266                     s = nStr2[Math.floor(d / 10)];
267                     //s += nStr1[d % 10];
268                     s += nStr1[parseInt(d % 10)];
269                     break;
270             }
271             return (s);
272         }
273         //在表格中显示公历和农历的日期,以及相关节日
274         var cld;
275         function drawCld(SY, SM) {
276             var TF = true;
277             var p1 = p2 = "";
278             var i, sD, s, size;
279             cld = new calendar(SY, SM);
280             GZ.innerHTML = '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【' + Animals[(SY - 4) % 12] + '】';    //生肖
281             for (i = 0; i < 42; i++) {
282                 sObj = eval('SD' + i);
283                 lObj = eval('LD' + i);
284                 sObj.className = '';
285                 sD = i - cld.firstWeek;
286                 if (sD > -1 && sD < cld.length) { //日期内
287                     sObj.innerHTML = sD + 1;
288                     if (cld[sD].isToday) {
289                         sObj.style.color = '#9900FF'; //今日颜色
290                     } else {
291                         sObj.style.color = '';
292                     }
293                     if (cld[sD].lDay == 1) { //显示农历月
294                         lObj.innerHTML = '<b>' + (cld[sD].isLeap ? '闰' : '') + cld[sD].lMonth + '月' + (monthDays(cld[sD].lYear, cld[sD].lMonth) == 29 ? '小' : '大') + '</b>';
295                     }
296                     else { //显示农历日
297                         lObj.innerHTML = cDay(cld[sD].lDay);
298                     }
299                     var Slfw = Ssfw = null;
300                     s = cld[sD].solarFestival;
301                     for (var ipp = 0; ipp < lFtv.length; ipp++) {    //农历节日
302                         if (parseInt(lFtv[ipp].substr(0, 2)) === parseInt(cld[sD].lMonth)) {
303                             if (parseInt(lFtv[ipp].substr(2, 4)) === parseInt(cld[sD].lDay)) {
304                                 lObj.innerHTML = lFtv[ipp].substr(5);
305                                 Slfw = lFtv[ipp].substr(5);
306                             }
307                         }
308                         if (12 == (cld[sD].lMonth)) {    //判断是否为除夕
309                             if (eve == (cld[sD].lDay)) { lObj.innerHTML = "除夕"; Slfw = "除夕"; }
310                         }
311                     }
312                     for (var ipp = 0; ipp < sFtv.length; ipp++) {    //公历节日
313                         if (parseInt(sFtv[ipp].substr(0, 2)) == (SM + 1)) {
314                             if (parseInt(sFtv[ipp].substr(2, 4)) == (sD + 1)) {
315                                 lObj.innerHTML = sFtv[ipp].substr(5);
316                                 Ssfw = sFtv[ipp].substr(5);
317                             }
318                         }
319                     }
320                     if ((SM + 1) == 5) {    //母亲节
321                         if (fat == 0) {
322                             if ((sD + 1) == 7) { Ssfw = "母亲节"; lObj.innerHTML = "母亲节" }
323                         }
324                         else if (fat < 9) {
325                             if ((sD + 1) == ((7 - fat) + 8)) { Ssfw = "母亲节"; lObj.innerHTML = "母亲节" }
326                         }
327                     }
328                     if ((SM + 1) == 6) {    //父亲节
329                         if (mat == 0) {
330                             if ((sD + 1) == 14) { Ssfw = "父亲节"; lObj.innerHTML = "父亲节" }
331                         }
332                         else if (mat < 9) {
333                             if ((sD + 1) == ((7 - mat) + 15)) { Ssfw = "父亲节"; lObj.innerHTML = "父亲节" }
334                         }
335                     }
336                     if (s.length <= 0) {    //设置节气的颜色
337                         s = cld[sD].solarTerms;
338                         if (s.length > 0) s = s.fontcolor('limegreen');
339                     }
340                     if (s.length > 0) { lObj.innerHTML = s; Slfw = s; }    //节气
341                     if ((Slfw != null) && (Ssfw != null)) {
342                         lObj.innerHTML = Slfw + "/" + Ssfw;
343                     }
344                 }
345                 else { //非日期
346                     sObj.innerHTML = '';
347                     lObj.innerHTML = '';
348                 }
349             }
350         }
351         //在下拉列表中选择年月时,调用自定义函数drawCld(),显示公历和农历的相关信息
352         function changeCld() {
353             var y, m;
354             y = CLD.SY.selectedIndex + 1900;
355             m = CLD.SM.selectedIndex;
356             drawCld(y, m);
357         }
358         //用自定义变量保存当前系统中的年月日
359         var Today = new Date();
360         var tY = Today.getFullYear();
361         var tM = Today.getMonth();
362         var tD = Today.getDate();
363         //打开页时,在下拉列表中显示当前年月,并调用自定义函数drawCld(),显示公历和农历的相关信息
364         function initial() {
365             CLD.SY.selectedIndex = tY - 1900;
366             CLD.SM.selectedIndex = tM;
367             drawCld(tY, tM);
368         }
369     </script>
370 </body>
371 
372 </html>

猜你喜欢

转载自www.cnblogs.com/yijiahao/p/11706206.html