wuxiren123

          如何利用自定義函數(shù)把陽歷轉(zhuǎn)換成陰歷

          數(shù)據(jù)庫保存的是陽歷日期,有時候會遇到把陽歷換成陰歷的需求,例如下圖把陽歷轉(zhuǎn)換成陰歷。


          這個問題是我在開發(fā)報表過程中遇到的一個小需求,利用的工具是FineReport8.0版本,解決思路是首先定義一個可以將陽歷轉(zhuǎn)為陰歷的類,然后自定義FineReport函數(shù),在run方法中獲取年月日參數(shù)并調(diào)用之前的類將陽歷轉(zhuǎn)為陰歷,最終返回給報表。

          實現(xiàn)步驟:

          1、  陽歷轉(zhuǎn)陰歷的類

          FineReport里面會提供一個現(xiàn)成的農(nóng)歷日歷工具類SolarToLunar,該類中通過today(intyear, int month, int day)方法可將輸入的年、月、日對應(yīng)的陽歷轉(zhuǎn)為陰歷日期,完整代碼入下:

          package com.fr.function;
          import java.text.SimpleDateFormat;
          import java.util.Calendar;
          import java.util.Date;
          import java.util.GregorianCalendar;
          import java.util.Locale;
          public class SolarToLunar {
              final private 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 };

              final private static int[] year20 = new int[] { 1, 4, 1, 2, 1, 2, 1, 1, 2,
                      1, 2, 1 };

              final private static int[] year19 = new int[] { 0, 3, 0, 1, 0, 1, 0, 0, 1,
                      0, 1, 0 };

              final private static int[] year2000 = new int[] { 0, 3, 1, 2, 1, 2, 1, 1,
                      2, 1, 2, 1 };

              public final static String[] nStr1 = new String[] { "", "正", "二", "三", "四",
                      "五", "六", "七", "八", "九", "十", "十一", "十二" };

              private final static String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊",
                      "己", "庚", "辛", "壬", "癸" };

              private final static String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰",
                      "巳", "午", "未", "申", "酉", "戌", "亥" };

              private final static String[] Animals = new String[] { "鼠", "牛", "虎", "兔",
                      "龍", "蛇", "馬", "羊", "猴", "雞", "狗", "豬" };

              private final static String[] solarTerm = new String[] { "小寒", "大寒", "立春",
                      "雨水", "驚蟄", "春分", "清明", "谷雨", "立夏", "小滿", "芒種", "夏至", "小暑", "大暑",
                      "立秋", "處暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };

              private final static String[] sFtv = new String[] { "0101*元旦", "0214 情人節(jié)",
                      "0308 婦女節(jié)", "0312 植樹節(jié)", "0315 消費者權(quán)益日", "0401 愚人節(jié)", "0501 勞動節(jié)",
                      "0504 青年節(jié)", "0512 護士節(jié)", "0601 兒童節(jié)", "0701 建黨節(jié)", "0801 建軍節(jié)",
                      "0808 父親節(jié)", "0909 毛澤東逝世紀念", "0910 教師節(jié)", "0928 孔子誕辰", "1001*國慶節(jié)",
                      "1006 老人節(jié)", "1024 聯(lián)合國日", "1112 孫中山誕辰", "1220 澳門回歸", "1225 圣誕節(jié)",
                      "1226 毛澤東誕辰" };

              private final static String[] lFtv = new String[] { "0101*農(nóng)歷春節(jié)",
                      "0115 元宵節(jié)", "0505 端午節(jié)", "0707 七夕情人節(jié)", "0815 中秋節(jié)", "0909 重陽節(jié)",
                      "1208 臘八節(jié)", "1224 小年", "0100*除夕" };

              /**
               * 傳回農(nóng)歷 y年的總天數(shù)
               * 
               * 
          @param y
               * 
          @return
               
          */
              final private static int lYearDays(int y) {
                  int i, sum = 348;
                  for (i = 0x8000; i > 0x8; i >>= 1) {
                      if ((lunarInfo[y - 1900] & i) != 0)
                          sum += 1;
                  }
                  return (sum + leapDays(y));
              }

              /**
               * 傳回農(nóng)歷 y年閏月的天數(shù)
               * 
               * 
          @param y
               * 
          @return
               
          */
              final private static int leapDays(int y) {
                  if (leapMonth(y) != 0) {
                      if ((lunarInfo[y - 1900] & 0x10000) != 0)
                          return 30;
                      else
                          return 29;
                  } else
                      return 0;
              }

              /**
               * 傳回農(nóng)歷 y年閏哪個月 1-12 , 沒閏傳回 0
               * 
               * 
          @param y
               * 
          @return
               
          */
              final private static int leapMonth(int y) {
                  return (int) (lunarInfo[y - 1900] & 0xf);
              }

              /**
               * 傳回農(nóng)歷 y年m月的總天數(shù)
               * 
               * 
          @param y
               * 
          @param m
               * 
          @return
               
          */
              final private static int monthDays(int y, int m) {
                  if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
                      return 29;
                  else
                      return 30;
              }

              /**
               * 傳回農(nóng)歷 y年的生肖
               * 
               * 
          @param y
               * 
          @return
               
          */
              final public static String AnimalsYear(int y) {
                  return Animals[(y - 4) % 12];
              }

              /**
               * 傳入 月日的offset 傳回干支,0=甲子
               * 
               * 
          @param num
               * 
          @return
               
          */
              final private static String cyclicalm(int num) {
                  return (Gan[num % 10] + Zhi[num % 12]);
              }

              /**
               * 傳入 offset 傳回干支, 0=甲子
               * 
               * 
          @param y
               * 
          @return
               
          */
              final public static String cyclical(int y) {
                  int num = y - 1900 + 36;
                  return (cyclicalm(num));
              }

              /**
               * 傳出農(nóng)歷.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6
               * 
               * 
          @param y
               * 
          @param m
               * 
          @return
               
          */
              final private long[] Lunar(int y, int m) {
                  long[] nongDate = new long[7];
                  int i = 0, temp = 0, leap = 0;
                  Date baseDate = new GregorianCalendar(1900 + 1900, 1, 31).getTime();
                  Date objDate = new GregorianCalendar(y + 1900, m, 1).getTime();
                  long offset = (objDate.getTime() - baseDate.getTime()) / 86400000L;
                  if (y < 2000)
                      offset += year19[m - 1];
                  if (y > 2000)
                      offset += year20[m - 1];
                  if (y == 2000)
                      offset += year2000[m - 1];
                  nongDate[5] = offset + 40;
                  nongDate[4] = 14;

                  for (i = 1900; i < 2050 && offset > 0; i++) {
                      temp = lYearDays(i);
                      offset -= temp;
                      nongDate[4] += 12;
                  }
                  if (offset < 0) {
                      offset += temp;
                      i--;
                      nongDate[4] -= 12;
                  }
                  nongDate[0] = i;
                  nongDate[3] = i - 1864;
                  leap = leapMonth(i); // 閏哪個月
                  nongDate[6] = 0;

                  for (i = 1; i < 13 && offset > 0; i++) {
                      // 閏月
                      if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) {
                          --i;
                          nongDate[6] = 1;
                          temp = leapDays((int) nongDate[0]);
                      } else {
                          temp = monthDays((int) nongDate[0], i);
                      }

                      // 解除閏月
                      if (nongDate[6] == 1 && i == (leap + 1))
                          nongDate[6] = 0;
                      offset -= temp;
                      if (nongDate[6] == 0)
                          nongDate[4]++;
                  }

                  if (offset == 0 && leap > 0 && i == leap + 1) {
                      if (nongDate[6] == 1) {
                          nongDate[6] = 0;
                      } else {
                          nongDate[6] = 1;
                          --i;
                          --nongDate[4];
                      }
                  }
                  if (offset < 0) {
                      offset += temp;
                      --i;
                      --nongDate[4];
                  }
                  nongDate[1] = i;
                  nongDate[2] = offset + 1;
                  return nongDate;
              }

              /**
               * 傳出y年m月d日對應(yīng)的農(nóng)歷.year0 .month1 .day2 .yearCyl3 .monCyl4 .dayCyl5 .isLeap6
               * 
               * 
          @param y
               * 
          @param m
               * 
          @param d
               * 
          @return
               
          */
              final public static long[] calElement(int y, int m, int d) {
                  long[] nongDate = new long[7];
                  int i = 0, temp = 0, leap = 0;
                  Date baseDate = new GregorianCalendar(0 + 1900, 0, 31).getTime();
                  Date objDate = new GregorianCalendar(y, m - 1, d).getTime();
                  long offset = (objDate.getTime() - baseDate.getTime()) / 86400000L;
                  nongDate[5] = offset + 40;
                  nongDate[4] = 14;

                  for (i = 1900; i < 2050 && offset > 0; i++) {
                      temp = lYearDays(i);
                      offset -= temp;
                      nongDate[4] += 12;
                  }
                  if (offset < 0) {
                      offset += temp;
                      i--;
                      nongDate[4] -= 12;
                  }
                  nongDate[0] = i;
                  nongDate[3] = i - 1864;
                  leap = leapMonth(i); // 閏哪個月
                  nongDate[6] = 0;

                  for (i = 1; i < 13 && offset > 0; i++) {
                      // 閏月
                      if (leap > 0 && i == (leap + 1) && nongDate[6] == 0) {
                          --i;
                          nongDate[6] = 1;
                          temp = leapDays((int) nongDate[0]);
                      } else {
                          temp = monthDays((int) nongDate[0], i);
                      }

                      // 解除閏月
                      if (nongDate[6] == 1 && i == (leap + 1))
                          nongDate[6] = 0;
                      offset -= temp;
                      if (nongDate[6] == 0)
                          nongDate[4]++;
                  }

                  if (offset == 0 && leap > 0 && i == leap + 1) {
                      if (nongDate[6] == 1) {
                          nongDate[6] = 0;
                      } else {
                          nongDate[6] = 1;
                          --i;
                          --nongDate[4];
                      }
                  }
                  if (offset < 0) {
                      offset += temp;
                      --i;
                      --nongDate[4];
                  }
                  nongDate[1] = i;
                  nongDate[2] = offset + 1;
                  return nongDate;
              }

              public final static String getChinaDate(int day) {
                  String a = "";
                  if (day == 10)
                      return "初十";
                  if (day == 20)
                      return "二十";
                  if (day == 30)
                      return "三十";
                  int two = (int) ((day) / 10);
                  if (two == 0)
                      a = "初";
                  if (two == 1)
                      a = "十";
                  if (two == 2)
                      a = "廿";
                  if (two == 3)
                      a = "三";
                  int one = (int) (day % 10);
                  switch (one) {
                  case 1:
                      a += "一";
                      break;
                  case 2:
                      a += "二";
                      break;
                  case 3:
                      a += "三";
                      break;
                  case 4:
                      a += "四";
                      break;
                  case 5:
                      a += "五";
                      break;
                  case 6:
                      a += "六";
                      break;
                  case 7:
                      a += "七";
                      break;
                  case 8:
                      a += "八";
                      break;
                  case 9:
                      a += "九";
                      break;
                  }
                  return a;
              }

              public static String today(int y, int m, int d) {
                  int year = y;
                  int month = m;
                  int date = d;
                  long[] l = calElement(year, month, date);
                  StringBuffer sToday = new StringBuffer();
                  try {

                      sToday.append(" 農(nóng)歷");
                      sToday.append(cyclical(year));
                      sToday.append('(');
                      sToday.append(AnimalsYear(year));
                      sToday.append(")年");
                      sToday.append(nStr1[(int) l[1]]);
                      sToday.append("月");
                      sToday.append(getChinaDate((int) (l[2])));
                      return sToday.toString();
                  } finally {
                      sToday = null;
                  }
              }

              private static SimpleDateFormat sdf = new SimpleDateFormat(
                      "yyyy年M月d日 EEEEE");

              /**
               * 農(nóng)歷日歷工具使用演示
               * 
               * 
          @param args
               
          */
              public static void main(String[] args) {
                  System.out.println(today(1988, 10, 27));
              }

          2、自定義FineReport函數(shù)

          自定義函數(shù)Lunar擴展于AbstractFunction,并重寫run方法,獲得年月日參數(shù)值,調(diào)用農(nóng)歷日歷工具類SolarToLunar的today方法,求得農(nóng)歷日期并返回,代碼如下:

          package com.fr.function;  

          import com.fr.script.AbstractFunction;
             
          public class Lunar extends AbstractFunction {  
              public Object run(Object[] args) {  
                  String result = "";  
                  int y = Integer.parseInt(args[0].toString());  
                  int m = Integer.parseInt(args[1].toString());  
                  int d = Integer.parseInt(args[2].toString());  
                  result = SolarToLunar.today(y, m, d);  
                  return result;  
              }  
          }

          3、編譯并運行

          編譯自定義函數(shù)

          編譯Lunar.java和SolarToLunar.java類生成Lunar.class和SolarToLunar.class文件拷貝至報表應(yīng)用所在目錄/WEB-INF/classes/com/fr/function下。

          注冊自定義函數(shù)

          啟動設(shè)計器,點擊服務(wù)器|函數(shù)管理器,新增函數(shù)取名為Lunar,選擇Lunar.class類,如下圖:


          自定義函數(shù)定義好了就可以在設(shè)計器中直接使用。

          比如在單元格中寫入公式=Lunar(2011,7,11),預(yù)覽模板,可以看到日期2011年7月11日陽歷就可以轉(zhuǎn)換成陰歷。

          若數(shù)據(jù)庫日期類型字段如圖:


          拖到模板設(shè)計界面,設(shè)置高級屬性,在自定義顯示值里面輸入公式Lunar(year($),month($),day($$$)),如下圖設(shè)置,則可把保存在數(shù)據(jù)庫里面的陽歷日期轉(zhuǎn)換成陰歷了。

          posted on 2016-06-02 14:48 喝水居然長肉 閱讀(161) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 太原市| 留坝县| 巴东县| 昭苏县| 巴楚县| 上虞市| 安西县| 嵊泗县| 横峰县| 岑溪市| 福建省| 怀安县| 南开区| 巨鹿县| 赤峰市| 哈尔滨市| 江安县| 贵阳市| 溆浦县| 康平县| 陈巴尔虎旗| 彭山县| 石狮市| 横山县| 衡阳县| 白山市| 怀集县| 昔阳县| 蓬莱市| 石柱| 韶关市| 吐鲁番市| 葫芦岛市| 普格县| 马公市| 樟树市| 衡山县| 达州市| 高州市| 永城市| 犍为县|