当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>Java入门

中国农历二百年算法及年历程序分析二

      // 注意:闰月 m < 0

      int index = y - baseChineseYear + baseIndex;

      int v = 0;

      int l = 0;

      int d = 30;

      if (1<=m && m<=8) {

         v = chineseMonths[2*index];

         l = m - 1;

         if ( ((v>>l)&0x01)==1 ) d = 29;

      } else if (9<=m && m<=12) {

         v = chineseMonths[2*index+1];

         l = m - 9;

         if ( ((v>>l)&0x01)==1 ) d = 29;

      } else {

         v = chineseMonths[2*index+1];

         v = (v>>4)&0x0F;

         if (v!=Math.abs(m)) {

            d = 0;

         } else {

            d = 29;

            for (int i=0; i

               if (bigLeapMonthYears[i]==index) {

                  d = 30;

                  break;

               }

            }

         }

      }

      return d;

   }

   public static int nextChineseMonth(int y, int m) {

      int n = Math.abs(m) + 1;

      if (m>0) {

         int index = y - baseChineseYear + baseIndex;

         int v = chineseMonths[2*index+1];

         v = (v>>4)&0x0F;

         if (v==m) n = -m;

      }

      if (n==13) n = 1;

      return n;

   }

   private static char[][] sectionalTermMap = {

   {7,6,6,6,6,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,5,5,5,5,5,4,5,5},

   {5,4,5,5,5,4,4,5,5,4,4,4,4,4,4,4,4,3,4,4,4,3,3,4,4,3,3,3},

   {6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},

   {5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,4,4,5,5,4,4,4,5,4,4,4,4,5},

   {6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},

   {6,6,7,7,6,6,6,7,6,6,6,6,5,6,6,6,5,5,6,6,5,5,5,6,5,5,5,5,4,5,5,5,5},

   {7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7},

   {8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},

   {8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,7},

   {9,9,9,9,8,9,9,9,8,8,9,9,8,8,8,9,8,8,8,8,7,8,8,8,7,7,8,8,8},

   {8,8,8,8,7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,7},

   {7,8,8,8,7,7,8,8,7,7,7,8,7,7,7,7,6,7,7,7,6,6,7,7,6,6,6,7,7}

   };

   private static char[][] sectionalTermYear = {

   {13,49,85,117,149,185,201,250,250},

   {13,45,81,117,149,185,201,250,250},

   {13,48,84,112,148,184,200,201,250},

   {13,45,76,108,140,172,200,201,250},

   {13,44,72,104,132,168,200,201,250},

   {5 ,33,68,96 ,124,152,188,200,201},

   {29,57,85,120,148,176,200,201,250},

   {13,48,76,104,132,168,196,200,201},

   {25,60,88,120,148,184,200,201,250},

   {16,44,76,108,144,172,200,201,250},

   {28,60,92,124,160,192,200,201,250},

   {17,53,85,124,156,188,200,201,250}

   };

   private static char[][] principleTermMap = {

   {21,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,20,20,20,20,20,19,

      20,20,20,19,19,20},

   {20,19,19,20,20,19,19,19,19,19,19,19,19,18,19,19,19,18,18,19,19,18,

      18,18,18,18,18,18},

   {21,21,21,22,21,21,21,21,20,21,21,21,20,20,21,21,20,20,20,21,20,20,

      20,20,19,20,20,20,20},

   {20,21,21,21,20,20,21,21,20,20,20,21,20,20,20,20,19,20,20,20,19,19,

      20,20,19,19,19,20,20},

   {21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,21,21,20,20,

      21,21,20,20,20,21,21},

   {22,22,22,22,21,22,22,22,21,21,22,22,21,21,21,22,21,21,21,21,20,21,

      21,21,20,20,21,21,21},

   {23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,23,23,22,22,

      22,23,22,22,22,22,23},

   {23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,

      23,23,22,22,22,23,23},

   {23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,23,23,22,22,

      23,23,22,22,22,23,23},

   {24,24,24,24,23,24,24,24,23,23,24,24,23,23,23,24,23,23,23,23,22,23,

      23,23,22,22,23,23,23},

   {23,23,23,23,22,23,23,23,22,22,23,23,22,22,22,23,22,22,22,22,21,22,

      22,22,21,21,22,22,22},

   {22,22,23,23,22,22,22,23,22,22,22,22,21,22,22,22,21,21,22,22,21,21,

      21,22,21,21,21,21,22}

   };

   private static char[][] principleTermYear = {

   {13,45,81,113,149,185,201},

   {21,57,93,125,161,193,201},

   {21,56,88,120,152,188,200,201},

   {21,49,81,116,144,176,200,201},

   {17,49,77,112,140,168,200,201},

   {28,60,88,116,148,180,200,201},

   {25,53,84,112,144,172,200,201},

   {29,57,89,120,148,180,200,201},

   {17,45,73,108,140,168,200,201},

   {28,60,92,124,160,192,200,201},

   {16,44,80,112,148,180,200,201},

   {17,53,88,120,156,188,200,201}

   };

   public int computeSolarTerms() {

      if (gregorianYear<1901 || gregorianYear>2100) return 1;

      sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth);

      principleTerm = principleTerm(gregorianYear, gregorianMonth);

      return 0;

   }

   public static int sectionalTerm(int y, int m) {

      if (y<1901 || y>2100) return 0;

      int index = 0;

      int ry = y-baseYear+1;

      while (ry>=sectionalTermYear[m-1][index]) index++;

      int term = sectionalTermMap[m-1][4*index+ry%4];

      if ((ry == 121)&&(m == 4)) term = 5;

      if ((ry == 132)&&(m == 4)) term = 5;

      if ((ry == 194)&&(m == 6)) term = 6;

      return term;

   }

   public static int principleTerm(int y, int m) {

      if (y<1901 || y>2100) return 0;

      int index = 0;

      int ry = y-baseYear+1;

      while (ry>=principleTermYear[m-1][index]) index++;

      int term = principleTermMap[m-1][4*index+ry%4];

      if ((ry == 171)&&(m == 3)) term = 21;

      if ((ry == 181)&&(m == 5)) term = 21;

      return term;

   }

   public String toString() {

      StringBuffer buf = new StringBuffer();

      buf.append("Gregorian Year: "+gregorianYear+"\n");

      buf.append("Gregorian Month: "+gregorianMonth+"\n");

      buf.append("Gregorian Date: "+gregorianDate+"\n");

      buf.append("Is Leap Year: "+isGregorianLeap+"\n");

      buf.append("Day of Year: "+dayOfYear+"\n");

      buf.append("Day of Week: "+dayOfWeek+"\n");

      buf.append("Chinese Year: "+chineseYear+"\n");

      buf.append("Heavenly Stem: "+((chineseYear-1)%10)+"\n");

      buf.append("Earthly Branch: "+((chineseYear-1)%12)+"\n");

      buf.append("Chinese Month: "+chineseMonth+"\n");

      buf.append("Chinese Date: "+chineseDate+"\n");

      buf.append("Sectional Term: "+sectionalTerm+"\n");

      buf.append("Principle Term: "+principleTerm+"\n");

      return buf.toString();

   }

   public String[] getYearTable() {

      setGregorian(gregorianYear,1,1);

      computeChineseFields();

      computeSolarTerms();

      String[] table = new String[58]; // 6*9 + 4

      table[0] = getTextLine(27, "公历年历:"+gregorianYear);

      table[1] = getTextLine(27, "农历年历:"+(chineseYear+1)

         + " ("+stemNames[(chineseYear+1-1)%10]

         + branchNames[(chineseYear+1-1)%12]

         + " - "+animalNames[(chineseYear+1-1)%12]+"年)");

      int ln = 2;

      String blank  = "                                         "

              +"  " + "                                         ";

      String[] mLeft = null;

      String[] mRight = null;

      for (int i=1; i<=6; i++) {

         table[ln] = blank;

         ln++;

         mLeft = getMonthTable();

         mRight = getMonthTable();

         for (int j=0; j

            String line = mLeft[j] + "  " + mRight[j];

            table[ln] = line;

            ln++;

         }

      }

      table[ln] = blank;

      ln++;

      table[ln] = getTextLine(0,

         "##/## - 公历日期/农历日期,(*)#月 - (闰)农历月第一天");

      ln++;

      return table;

   }

   public static String getTextLine(int s, String t) {

      String str  = "                                         "

              +"  " + "                                         ";

      if (t!=null && s

         str = str.substring(0,s) + t + str.substring(s+t.length());

      return str;

   }

   private static String[] monthNames =

      {"一","二","三","四","五","六","七","八","九","十","十一","十二"};

   public String[] getMonthTable() {

      setGregorian(gregorianYear,gregorianMonth,1);

      computeChineseFields();

      computeSolarTerms();

      String[] table = new String[8];

      String title  = null;

      if (gregorianMonth<11) title  = "                   ";

      else title  = "                 ";

      title = title + monthNames[gregorianMonth-1] + "月"

                    + "                   ";

      String header = "   日    一    二    三    四    五    六 ";

      String blank  = "                                          ";

      table[0] = title;

      table[1] = header;

      int wk = 2;

      String line = "";

      for (int i=1; i

         line += "     " + ' ';

      }

      int days = daysInGregorianMonth(gregorianYear,gregorianMonth);

      for (int i=gregorianDate; i<=days; i++) {

         line += getDateString() + ' ';

         rollUpOneDay();

         if (dayOfWeek==1) {

            table[wk] = line;

            line = "";

            wk++;

         }

      }

      for (int i=dayOfWeek; i<=7; i++) {

         line += "     " + ' ';

      }

      table[wk] = line;

      for (int i=wk+1; i

         table[i] = blank;

      }

      for (int i=0; i

         table[i] = table[i].substring(0,table[i].length()-1);

      }

 

      return table;

   }

   private static String[] chineseMonthNames =

      {"正","二","三","四","五","六","七","八","九","十","冬","腊"};

   private static String[] principleTermNames =

      {"雨水","春分","谷雨","夏满","夏至","大暑","处暑","秋分","霜降",

       "小雪","冬至","大寒"};

   private static String[] sectionalTermNames =

      {"立春","惊蛰","清明","立夏","芒种","小暑","立秋","白露","寒露",

       "立冬","大雪","小寒"};

   public String getDateString() {

      String str = "*  /  ";

      String gm = String.valueOf(gregorianMonth);

      if (gm.length()==1) gm = ' ' + gm;

      String cm = String.valueOf(Math.abs(chineseMonth));

      if (cm.length()==1) cm = ' ' + cm;

      String gd = String.valueOf(gregorianDate);

      if (gd.length()==1) gd = ' ' + gd;

      String cd = String.valueOf(chineseDate);

      if (cd.length()==1) cd = ' ' + cd;

      if (gregorianDate==sectionalTerm) {

         str = " "+sectionalTermNames[gregorianMonth-1];

      } else if (gregorianDate==principleTerm) {

         str = " "+principleTermNames[gregorianMonth-1];

      } else if (chineseDate==1 && chineseMonth>0) {

           str = " "+chineseMonthNames[chineseMonth-1]+"月";

      } else if (chineseDate==1 && chineseMonth<0) {

           str = "*"+chineseMonthNames[-chineseMonth-1]+"月";

      } else {

           str = gd+'/'+cd;

      }

      return str;

   }

   public int rollUpOneDay() {

      dayOfWeek = dayOfWeek%7 + 1;

      dayOfYear++;

      gregorianDate++;

      int days = daysInGregorianMonth(gregorianYear,gregorianMonth);

      if (gregorianDate>days) {

         gregorianDate = 1;

         gregorianMonth++;

         if (gregorianMonth>12) {

            gregorianMonth = 1;

            gregorianYear++;

            dayOfYear = 1;

            isGregorianLeap = isGregorianLeapYear(gregorianYear);

         }

         sectionalTerm = sectionalTerm(gregorianYear,gregorianMonth);

         principleTerm = principleTerm(gregorianYear,gregorianMonth);

      }

      chineseDate++;

      days = daysInChineseMonth(chineseYear,chineseMonth);

      if (chineseDate>days) {

         chineseDate = 1;

         chineseMonth = nextChineseMonth(chineseYear,chineseMonth);

         if (chineseMonth==1) chineseYear++;

      }

      return 0;

   }

}

[/HTML]

 

中国二百年年历 1901 年至 2100 年

 

我用上面这个程式制作了二百年年历,1901 年至 2100 年,全部收录在这本书中。

 

年历格式说明:

 

农历日期列在公历日期后面。

节气用节气名称标明。

农历每月第一天用月份名称标明。

例如,2000 年一月的表达格式如下:

[HTML]

                   一月

   日    一    二    三    四    五    六

                                     1/25

 2/26  3/27  4/28  5/29  立春  腊月  8/ 2

 9/ 3 10/ 4 11/ 5 12/ 6 13/ 7 14/ 8 15/ 9

16/10 17/11 18/12 19/13 20/14  雨水 22/16

23/17 24/18 25/19 26/20 27/21 28/22 29/23

30/24 31/25

[/HTML]

 

其中:

 

"1/25" - 表示公历 1 号和农历 25 号。

"立春" - 表示节气。

"腊月" - 表示农历 12 月第一天。

相关内容
赞助商链接