zoukankan      html  css  js  c++  java
  • 在线万年历

    在线万年历

         1.概述

         在计算机没有普及的年代,要查找多年前某天对应的农历日期,就不得不翻阅一本厚厚的万年历进行查询。如今,随着计算机网络的普及,只要利用任意搜索引擎搜索“在线万年历”就可以搜索出很多功能强大的万年历。本实例向大家介绍的是在线万年历的实现过程,通过本程序可以查询从1901年到2049年中任何一天的具体的农历日期、节日、星期等信息。在线万年历可以作为一个单独的程序来运行也可以嵌套在某网站中作为一个子模块来实现。例如将在线万年历系统嵌套在留言板模块中,在“备忘录”子模块中添加万年历功能。

         2.设计思路

         根据在线万年历程序的要求,笔者将万年历的布局设计为显示公历日期、农历日期、节日、某年的生肖,并需要添加下拉列表提示用户要查看哪一年、哪一月的日期,页面中还添加了“上一年”、“下一年”、“上一月”、“下一月”、“本月”按钮方便用户操作。

         3.技术要点

         在万年历程序中,不管是获取农历日期还是农历日期都离不开时间类的支持,下面向读者介绍Java中处理时间日期的类。

       (1)Calendar类。

              Calendar类是一个抽象类,该类为特定瞬间与一组诸如YWAR、MONTH、DAY_OF_MONTH、HOUR等日历之间的转换提供了方法,并为操作日历字段例如获取下星期的      日期提供了方法。

         下面是该类中的常用方法:

                  1、getInstance()方法,该方法是类方法,以获得此类型的一个通用的对象。getInstance()方法返回一个Calendar对象。可以通过如下语句获取Calendar对象。

                             Calendar today1 = Calendar.getInstance();

                  2、getTime()方法,该方法可获取表示此Calendar时间值的Date对象。例如获取当前系统时间可通过如下代码实现:

                            Calendar rightNow = Calendar.getInstance();

                            Date date = rightNow.getTime();

                 3、setTime()方法,该方法使用给定的Date设置此Canlendar的时间。语法格式为:

                            setTime(Date date)

                 4、set()方法,该方法提供了多种重载形式,用来设置给定的日历字段设置为给定值。例如可以通过如下语句重新设置日属性。

                            today1.set(Calendar.DAY_OF_MONTH,1 );

                            可以通过如下语句获取月属性。

                            today1.set(Calendar.MONTH,4 );

     

        (2)获取母亲节和父亲节日期。

               在实现万年历时,一年当中的大多节日固定在某一天的。而母亲节和父亲节的日期并不是固定的。它被定义为每年5月份的第2个星期日和6月的3个星期日。这样就需要根        据月份和日期进行判断。

               在实现获取母亲节和父亲节具体是哪一天时,首先要判断当前月的第一天是否是周日,如果是周日,则母亲节(父亲节)在该月的第2周(第3周),否则在该月的第3周        (第4周)。

               本实例中获取母亲节与父亲节是周几的相关代码如下:

                 Calendar today1 = Calendar.getInstance();

                 today1.set(Calendar.DAY_OF_MONTH,1 );

                 today1.set(Calendar.MONTH,tempCal.get(Calendar.MONTH) );

                 today1.set(Calendar.YEAR,tempCal.get(Calendar.YEAR));

                 int week=today1.get(Calendar.DAY_OF_WEEK); //获取指定月的第一天是周几

                 int tempWeek=0;

                 if(week!=1)

                   { //如果不是周日

                              tempWeek=1;

                   }

                 else

                  {

                              tempWeek=0;

                   }

               if(tempCal.get(Calendar.MONTH)==4)

                 { //如果为5月,表示母亲节

                              tempWeek+=2;

                 }

                  else

                 { //为父亲节

                              tempWeek+=3;

                 }

               return tempWeek;

     

         4.开发步骤

           本实例实现的带农历的万年历是通过JSP+JavaBean技术实现的,下面首先向大家介绍万年历核心类的编写。

          (1)在类StringUtils中定义方法formatNO(),该方法用户将整型数字格式为指定长度。该方法中有两个int型参数,分别代表要格式化的数字str和格式化后字符串的长度            length。返回值为格式化后的字符串。

           具体代码如下:

                 

       public String formatNO(int str, int length)
    
                    {
    
                             float ver = Float.parseFloat(System.getProperty("java.specification.version")); //获取JDK的版本
    
                             String laststr = "";
    
                             if (ver < 1.5) { //JDK1.5以下版本执行的语句
    
                                                         try {
    
                                                                      NumberFormat formater = NumberFormat.getNumberInstance(); //NumberFormat为所有数值格式的抽象类的基类
    
                                                                      formater.setMinimumIntegerDigits(length); //设置数的整数部分允许的最小位数
    
                                                                       laststr = formater.format(str).toString().replace(",", ""); //字符串格式化
    
                                                              } catch (Exception e) {
    
                                                                                                    System.out.println("格式化字符串时的错误信息:" + e.getMessage()); //输出异常信息
    
                                                                                               }
    
                                                }
    
                              else { //JDK1.5以上版本执行的语句
    
                                                   Integer[] arr=new Integer[1]; //定义Integer数组
    
                                                   arr[0]=new Integer(str); //为Integer数组赋值
    
                                                    laststr = String.format("%0" + length + "d", arr);
    
                                      }
    
                             return laststr; //将格式化后的字符串返回
    
                 }

     

     (2)首次编写万年历核心类,该类包含生成万年历时需要的核心方法,包括获取农历y年的总天数、获取y年第n个节气为几日、获取公历节日、获取农历节日等信息。创建类MyCalendar,该类保存在包com.tools中,并定义该类中所需的全局变量。关键代码如下:

                      

    package com.tools; //定义该类所在的包
    
                      import java.text.ParseException; //导入该类中所需要的类包
    
                      import java.text.SimpleDateFormat;
    
                      import java.util.Calendar;
    
                      import java.util.Date;
    
                      import com.tools.StringUtils;
    
                      public class MyCalendar {
    
                                                              private int year; //历年
    
                                                              private int month; //历月
    
                                                              private int day; //历日
    
                                                              private boolean leap; //闰年
    
                                                              final static String chineseNumber[] = { "一", "二", "三", "四", "五", "六", "七",
    
                                                               "八", "九", "十","十一","十二''
    
                                                        }; //中文数字
    
                    static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日"); //日期格式
    
                    final static long[] lunarInfo = new long[] {  0x04bd8, 0x04ae0, 0x0a570,
    
                                                                                 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
    
                                                                                 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0,
    
                                                                                 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50,
    
                                                                                 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566,
    
                                                                                 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0,
    
                                                                                 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4,
    
                                                                                 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550,
    
                                                                                 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950,
    
                                                                                 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260,
    
                                                                                 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0,
    
                                                                                 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
    
                                                                                 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40,
    
                                                                                 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3,
    
                                                                                 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960,
    
                                                                                 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0,
    
                                                                                 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9,
    
                                                                                 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0,
    
                                                                                 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65,
    
                                                                                 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0,
    
                                                                                 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2,
    
                                                                                 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0}; //农历日期
    
                    String[] solarTerm = {"小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨",
    
                                                    "立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分",
    
                                                    "寒露","霜降","立冬","小雪","大雪","冬至"}; //节气的中文名称
    
                   int[] sTermInfo ={0,21208,42467,63836,85337,107014,128867,150921,173149,195551,
    
                                             218072,240693,263343,285989,308563,331033,353350,375494,397447,419210,
    
                                             440795,462224,483532,504758}; //各节气与小寒之间的时间差,单位为分钟
    
                 }

     

      (3)定义返回某年的第n个节气为几日方法sTerm(),该方法包含有两个int型参数,分别代表历年y和第n个节气。返回具体节气所在的日期。具体代码如下:

                     //返回某年的第n个节气为几日(从0小寒起算)

                       

       public int sTerm(int y,int n) {
    
                                                                       Calendar offDate = Calendar.getInstance();
    
                                                                       offDate.set(1900, 0, 6, 2, 5, 0); //设置基准日期为1900年1月6日2:05:00 AM
    
                                                                       long temp = offDate.getTime().getTime();
    
                                                                       offDate.setTime(new Date((long) ((31556925974.7 * (y - 1900) + sTermInfo[n] * 60000L) + temp)));
    
                                                                       return offDate.get(Calendar.DAY_OF_MONTH); //将具体的天数返回
    
                                                                 }

     

    (4)编写获取农历某年闰月的天数方法leapDays(),该方法有一个int型参数,用于指定年份,返回值为农历某年闰月的天数,具体代码如下:

                       final private static int leapDays(int y) {

                                                                                 if (leapMonth(y) != 0)

                                                                                             { //如果指定参数不为0

                                                                                                     if ((lunarInfo[y - 1900] & 0x10000) != 0) {

                                                                                                                                                                         return 30;

                                                                                                                                                                   }

                                                                                                    else

                                                                                                                {

                                                                                                                     return 29;

                                                                                                                 }

                                                                                              }

                                                                               else {

                                                                                          return 0;

                                                                                     }

                                                                         }

     

     

      (5)创建获取农历y年的总天数方法yearDays(),该方法有一个int型参数,用于指定年份,返回值为农历y年的总天数,具体代码如下:

                 

         final private static int yearDays(int y) {
    
                                                                                 int i, sum = 348; //sum表示没有闰月时农历年的天数
    
                                                                                 for (i = 0x8000; i > 0x8; i >>= 1) {
    
                                                                                                                                       if ((lunarInfo[y - 1900] & i) != 0)
    
                                                                                                                                           sum += 1; //农历y年有闰月
    
                                                                                                                                    }
    
                                                                                 return (sum + leapDays(y)); //返回农历y年的总天数
    
                                                                            }

    (6)编写获取农历y年哪个月是闰月方法leapMonth(),该方法有一个int型参数,用于指定年份,如果该年中没有闰月则返回0,否则将返回闰月的月份。具体代码如下:

                        

     final private static int leapMonth(int y) {
    
                                                                                         return (int) (lunarInfo[y - 1900] & 0xf);
    
                                                                               }

     

    (7)编写获取农历y年m月的总天数方法monthDays(),该方法有两个int型参数,分别是历年y和历月m。返回值为农历y年m月的总天数,具体代码如下:

                         

       final private static int monthDays(int y, int m) {
    
                                                                                                  if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
    
                                                                                                                   return 29;
    
                                                                                                   else
    
                                                                                                                   return 30;
    
                                                                                               }

     (8)编写获取某年生肖方法animalsYear(),该方法只有一个int型的参数,用于指定年份,返回值为y年的生肖。具体代码如下:

                     

       final public String animalsYear(int y) {
    
                                                                              final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇""马", "羊", "猴", "鸡", "狗", "猪"};
    
                                                                              return Animals[(y - 4) % 12];
    
                                                                            }

     

    (9)编写获取指定年份的干支方法cyclical(),该方法有一个int型参数,用于指定年份,返回值为农历y年的干支。具体代码如下:

                            

      final public String cyclical(int y) {
    
                                                                             int num = y - 1900 + 36;
    
                                                                             final String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚","辛", "壬", "癸" };
    
                                                                             final String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午","未", "申", "酉", "戌", "亥" };
    
                                                                             return (Gan[num % 10] + Zhi[num % 12]);
    
                                                                           }

     

     (10)编写计算公历节日方法getSFeast(),该方法有两个int型参数,分别为历月m和历日d,将公历节日返回,具体代码如下:

    public String getSFeast(int m,int d){
    String[] sFeast = {"0101 元旦","0214 情人节","0308 妇女节","0312 植树节",
    "0315 消费者权益日","0401 愚人节","0501 劳动节","0504 青年节","0512 护士节",
    "0601 儿童节","0701 建党节","0801 建军节","0910 教师节","0928 孔子诞辰",
    "1001 国庆节", "1006 老人节","1024 联合国日", "1224 平安夜","1225 圣诞节"};
    StringUtils su=new StringUtils();
    String tempDate=su.formatNO(m, 2)+su.formatNO(d, 2); //将历月和历日都格式化为2位
    String r="";
    for(int i=0;i<sFeast.length;i++){ //循环遍历字符串数组
    if(tempDate.equals(sFeast[i].substring(0,4))){ //如果历月历日与保存节日的数组中的前4位相等
    r=sFeast[i].substring(5); //获取节日名称
    break; //退出循环
    }
    }
    return r; //将节日名称返回
    }

    (11)编写计算农历节日方法getLFeast(),该方法有两个int型参数,分别为历月m个历日d,返回值为农历节日,具体代码如下:

    public String getLFeast(int m,int d){
    String[] lFeast ={"0101 春节","0115 元宵节","0505 端午节","0707 七夕情人节",
    "0715 中元节","0815 中秋节","0909 重阳节","1208 腊八节","1223 小年"}; //定义农历节日
    StringUtils su=new StringUtils();
    String tempDate=su.formatNO(m, 2)+su.formatNO(d, 2); //将历月和历日都格式化为2位
    String r="";
    for(int i=0;i<lFeast.length;i++){ //循环遍历农历保存农历节日数组
    if(tempDate.equals(lFeast[i].substring(0,4))){ //如果指定的历月历日与农历节日的前4位相等
    r=lFeast[i].substring(5); //获取农历节日名称
    break; //退出循环
    }
    }
    return r; //将农历节日返回
    }

    (12)编写获取母亲节与父亲节所在的周的方法getWeek(),该方法中有一个Calendar类型参数,该参数指定当前的日期对象,返回值为母亲节或父亲节所在的周,该方法的具体代码如下:

    public int getWeek(Calendar tempCal){
    //获取指定月的第一天的Calendar对象
    Calendar today1 = Calendar.getInstance();
    today1.set(Calendar.DAY_OF_MONTH,1 );
    today1.set(Calendar.MONTH,tempCal.get(Calendar.MONTH) );
    today1.set(Calendar.YEAR,tempCal.get(Calendar.YEAR));
    int week=today1.get(Calendar.DAY_OF_WEEK); //获取指定月的第一天是周几
    int tempWeek=0;
    if(week!=1){ //如果不是周日
    tempWeek=1;
    }else{
    tempWeek=0;
    }
    if(tempCal.get(Calendar.MONTH)==4){ //如果为5月,表示母亲节
    tempWeek+=2;
    }else{ //为父亲节
    tempWeek+=3;
    }
    return tempWeek; //将母亲节(父亲节)的具体日期返回
    }

      (13)编写转换农历日期中中文日期方法getChinaDayString(),该方法有一个int型参数,用于指定农历的历日,返回值为中文日期,具体代码如下:

    public static String getChinaDayString(int day) {
    String chineseTen[] = { "初", "十", "廿", "三" }; //定义中文农历日期需要的中文日期数组
    int n = day % 10 == 0 ? 9 : day % 10 - 1; 
    if (day > 30) //如果指定的参数大于30
    return ""; //返回null
    if (day == 10) //如果参数等于10
    return "初十"; //返回“初十”
    else //如果参数不等于十
    return chineseTen[day / 10] + chineseNumber[n]; //返回对应的中文日期
    }

    (14)编写转换农历日期中的中文日期方法myCalendar(),该方法只用一个Calendar类型参数,用于指定农历的历日,返回值为中文日期,具体代码如下:

    public String myCalendar(Calendar cal) {
    int yearCyl, monCyl, dayCyl; //定义int型变量,分别代表历年、历月、历日
    int leapMonth = 0;
    Date baseDate = null; //创建Date类型变量
    try {
    baseDate = chineseDateFormat.parse("1900年1月31日"); //将Date类型变量进行初始化
    } catch (ParseException e) {
    e.printStackTrace();
    }
    // 求出和1900年1月31日相差的天数
    int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
    dayCyl = offset + 40;
    monCyl = 14;
    用offset减去每农历年的天数计算当天是农历第几天,其中,i的最终值为农历的年份,offset是当年的第几天。
    int iYear, daysOfYear = 0;
    for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
    daysOfYear = yearDays(iYear);
    offset -= daysOfYear;
    monCyl += 12;
    }
    if (offset < 0) {
    offset += daysOfYear;
    iYear--;
    monCyl -= 12;
    }
    计算农历年份
    year = iYear;
    yearCyl = iYear - 1864;
    leapMonth = leapMonth(iYear); // 闰哪个月,1-12
    leap = false;
    // 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
    int iMonth, daysOfMonth = 0;
    for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
    // 闰月
    if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
    --iMonth;
    leap = true;
    daysOfMonth = leapDays(year);
    } else
    daysOfMonth = monthDays(year, iMonth);
    
    offset -= daysOfMonth;
    // 解除闰月
    if (leap && iMonth == (leapMonth + 1))
    leap = false;
    if (!leap)
    monCyl++;
    }
    offset为0时,并且刚才计算的月份是闰月,要校正
    if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
    if (leap) {
    leap = false;
    } else {
    leap = true;
    --iMonth;
    --monCyl;
    }
    }
    当offset小于0时,也需要校正
    if (offset < 0) {
    offset += daysOfMonth;
    --iMonth;
    --monCyl;
    }
    获取公历和农历节日。
    month = iMonth;
    day = offset + 1;
    int y=cal.get(Calendar.YEAR);
    int m=cal.get(Calendar.MONTH)+1;
    int d=cal.get(Calendar.DAY_OF_MONTH);
    String sFeast=getSFeast(m,d); //获取公历节日
    String lFeast=getLFeast(month,day); //获取农历节日
    String solarTerms="";
    获取节气
    if (d == sTerm(y, (m - 1) * 2))
    solarTerms = solarTerm[(m - 1) * 2];
    else if (d == sTerm(y, (m - 1) * 2 + 1))
    solarTerms = solarTerm[(m - 1) * 2 + 1];
    String tempStr="";
    if(!"".equals(sFeast)){
    tempStr=sFeast;
    }
    if(!"".equals(lFeast)){
    if("".equals(tempStr)){
    tempStr=lFeast;
    }else{
    tempStr=tempStr+"/"+lFeast;
    }
    }
    if(!"".equals(solarTerms)){
    if("".equals(tempStr)){
    tempStr=solarTerms;
    }else{
    tempStr=tempStr+"/"+solarTerms;
    }
    }
    判断是否为母亲节
    if(cal.get(Calendar.MONTH)==4){
    if(cal.get(Calendar.WEEK_OF_MONTH)==getWeek(cal) && cal.get(Calendar.DAY_OF_WEEK)==1){
    if(!"".equals(tempStr)){
    tempStr=tempStr+"/"+"母亲节";
    }else{
    tempStr="母亲节";
    }
    }
    }
    判断是否为父亲节
    if(cal.get(Calendar.MONTH)==5){
    if((cal.get(Calendar.WEEK_OF_MONTH)==getWeek(cal)) && (cal.get(Calendar.DAY_OF_WEEK)==1)){
    if(!"".equals(tempStr)){
    tempStr=tempStr+"/"+"父亲节";
    }else{
    tempStr="父亲节";
    }
    }
    }
    判断是否为闰月
    if(!"".equals(tempStr)){
    return "<font color='red'>"+tempStr+"</font>";
    }else{
    if(day==1){
    return (leap ? "闰" : "") + chineseNumber[month - 1] + "月";
    }else{
    return getChinaDayString(day);
    }
    }
    }

    (15)至此万年历核心类编写完成,在JSP页面中编写显示万年历代码。首先在index.jsp页面中通过<jsp:useBean>动作标记创建类MyCalendar、类TimeUtils实例,并指定其存储范围,具体代码如下:
      

       <jsp:useBean class="com.tools.MyCalendar" id="calendar" scope="request"/>
         <jsp:useBean class="com.tools.TimeUtils" id="tu" scope="request"/>


    (16)创建一个42个元素的一维数组,用于初始化万年历中的单元格,并将该数组的各元素设置为空字符串,具体代码如下:
       

      <%
              String days[]=new String[42]; //创建一个42个元素的一维数组,用于初始化万年历中的日期单元格
              for(int i=0;i<42;i++){
                                             days[i]=""; 
                                            }
        %>


    (17)根据要显示的月历信息生成月历中的公历日期,具体代码如下:

        

    <%
    Calendar today1 = Calendar.getInstance(); //创建Calendar类的对象
    SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy-MM-dd"); //指定日期格式
    int month=0;
    int year=0;
    GregorianCalendar currentDay = new GregorianCalendar();
    //当参数year不为空时,表示通过控制区对日历中显示的月份或年份进行改变
    if(request.getParameter("year")!=null && ! "".equals(request.getParameter("year"))){
    month=Integer.parseInt(request.getParameter("month"))-1;
    year= Integer.parseInt(request.getParameter("year")); 
    }else{ //采用默认值
    month=currentDay.get(Calendar.MONTH); //获取当前月
    year= currentDay.get(Calendar.YEAR); //获取当前年
    }
    int today=currentDay.get(Calendar.DAY_OF_MONTH); //获取当前日
    Calendar thisMonth=Calendar.getInstance(); //创建Calendar类的对象
    thisMonth.set(Calendar.MONTH, month );
    thisMonth.set(Calendar.YEAR, year );
    thisMonth.setFirstDayOfWeek(Calendar.SUNDAY);
    thisMonth.set(Calendar.DAY_OF_MONTH,1);
    int firstIndex=thisMonth.get(Calendar.DAY_OF_WEEK)-1; //获取显示月历中的第一天所在的星期
    int maxIndex=thisMonth.getActualMaximum(Calendar.DAY_OF_MONTH); //获取显示月历的总天数
    for(int i=0;i<maxIndex;i++){ //生成显示月历中的公历日期
    days[firstIndex+i]=String.valueOf(i+1);
    }
    %>


    (18)在页面的合适位置创建一个3行7列的表格,用于显示万年历。其中,第一行用于显示控制区,第二行用于显示日历的标头,第3行用于显示日期,关键代码如下:
        

    <table width="443" border="0" align="left" style="float:left" cellpadding="0" cellspacing="1" bordercolor="#FFFFFF" bgcolor="#F2F1EF">
    <tr bgcolor="FFFCF1">
    <td height="36" colspan="7" align="center" valign="middle" bgcolor="#AC8F67"><!--此处省略了显示控制区的代码-->
    </td>
    </tr>
    <tr bgcolor="C9B65A">
    <td width="44" height="40" align="center" bgcolor="#EBDFC9" class="word_red">日<br>
    SUN </font></td>
    <td width="44" height="40" align="center" bgcolor="#EBDFC9" class="word_darkGray">一<br>
    MON</td><!--此处省略了显示星期二至星期五的其他单元格的代码-->
    <td width="44" height="40" align="center" bgcolor="#EBDFC9" class="word_blue">六<br>
    SAT</font></td>
    </tr>
    <tr bgcolor="FFFCF1">
    <td align="center" bgcolor="<%=bgcolor%>" valign="middle"></td>
    </tr>
    </table>


    (19)创建表格中控制日历显示内容(指定年和月)的表单、表单元素及图片,关键代码如下:

    <form method="POST" action="main.jsp"><%=calendar.cyclical(year)+"("+calendar.animalsYear(year)+")"%><select name="year" onChange="this.form.submit();"> 
    <%for(int i=2049;i>=1901;i--){ %> 
    <option value="<%=i%>" <%if(i==year) out.println("selected");%>> 
    <%out.println(i);%> 
    </option> 
    <%}%> 
    </select>&nbsp;&nbsp;<select name="month" onChange="this.form.submit();"> 
    <%for(int i=1;i<=12;i++){%> 
    <option value="<%=i%>" <%if(i==month+1) out.println("selected");%>><%out.println(i);%></option> 
    <%}%> </select>月&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
    <% int ly,ny; 
    ly=year; 
    ny=year; 
    int last=month; 
    if (last<1){ 
    last=12; 
    ly--; 
    } 
    int next=month+1; 
    if (next>11){ 
    next=0; 
    ny++; 
    }
    if (year>1900){%>
    <a href="main.jsp?year=<%=year-1%>&month=<%=month+1%>"><img src="images/shang-nian.gif" width="17" height="18" border="0" alt="上一年"></a>
    <%}else{%>
    <img src="images/shang-nian.gif" width="17" height="18" border="0" alt="上一年">
    <%}
    if (ly>1900){ %>
    <a class="word_white" href="main.jsp?year=<%=ly%>&month=<%=last%>"><img src="images/shang-yue.gif" width="18" height="18" border="0" alt="上一月"></a>&nbsp;
    <% } else{%>
    <img src="images/shang-yue.gif" width="18" height="18" border="0" alt="上一月">
    <% } %> 
    <a class="word_white" href="main.jsp"><img src="images/ben-yue.gif" width="13" height="18" border="0" alt="本月"></a>
    <% if(ny<2050){ %> 
    <a class="word_white" href="main.jsp?year=<%=ny%>&month=<%=next+1%>"><img src="images/xia-yue.gif" width="18" height="18" border="0" alt="下一月"></a> 
    <% }else{%>
    <img src="images/xia-yue.gif" width="18" height="18" border="0" alt="下一月">
    <% } %>
    <%if(year<2049){%>
    <a href="main.jsp?year=<%=year+1%>&month=<%=month+1%>"><img src="images/xia-nian.gif" width="17" height="18" border="0" alt="下一年"></a>&nbsp; 
    <%}else{%>
    <img src="images/xia-nian.gif" width="13" height="14" border="0">&nbsp;
    <%}%>
    </form>


    (20)编写循环生成日历中内容代码,在生成日历内容时,需要调用MyCalendar类的myCalendar()方法生成农历日期。具体代码如下:

    </tr>
    <%String color = "#000000";
    String bgcolor = "FFFFFF";
    for (int j = 0; j < 6; j++) {%>
    <tr bgcolor="FFFCF1">
    <% for (int i = j * 7; i < (j + 1) * 7; i++) {
    switch ((i + 1) % 7) {
    case 6:
    case 2:
    case 3:
    case 4:
    case 5:
    color = "#000000";
    break;
    case 1:
    color = "#FF0000";
    break;
    case 0:
    color = "#1B789D";
    break;
    }
    if ((i - firstIndex + 1) == today) {
    bgcolor = "#C8E3F3"; //设置当天日期的背景颜色
    } else {
    bgcolor = "FFFFFF";
    }
    %>
    <td align="center" bgcolor="<%=bgcolor%>" valign="middle" <%if (!"".equals(days[i])) {%>
    <%
    int d = Integer.parseInt(days[i]);
    int week = tu.getWeek(year, month, d); //获取当前日期是星期几
    %>
    <%
    out.println("style="cursor:hand;" date=" + year + "-" + (month + 1) + "-" + d + "','',';return false;"><font color="" + color + "">" + d + "<br>");
    if (days[i] != "") {
    String str = year + "-" + (month + 1) + "-" + d;
    today1.setTime(chineseDateFormat.parse(str));
    out.println(calendar.myCalendar(today1)); //获取农历日期或是节假日
    }
    out.println("</font>");%>
    <%}%>
    </td>
    <%}%>
    </tr>
    
     
  • 相关阅读:
    SSM框架整合步骤
    Spring-data-jpa
    allure定制报告
    pytest常用选项
    staticmethod&classmethod&property
    __slot__
    python的参数传递
    闭包和装饰器
    内置高阶函数
    str
  • 原文地址:https://www.cnblogs.com/zkn11199/p/5566621.html
Copyright © 2011-2022 走看看