当前位置:   article > 正文

java万年历uml_Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(2) 自己封装的Calendar接口...

javachinesecalendar

1 packagecom.via.mce.monthcalendar.utils;2

3 importjava.util.Calendar;4 importjava.util.Date;5 importjava.util.GregorianCalendar;6 importjava.util.HashMap;7

8 /**

9 * 农历日历。
10 * 将农历从1901年到2100年之间各年、月的大小以及历年节气保存,然后基于这些数据进行计算。
11 *
12 * 新增了几个用于农历的常量属性字段,可以使用get()方法获取日历对应的值;
13 * 农历年、月、日还可以使用set()/add()/roll()方法设置,其他农历属性自动计算;
14 * 另外,还提供了getChinese(int field)方法用于获得农历的中文文字(仅适用于农历属性和星期)。
15 *

  • 16 *
  • CHINESE_YEAR - 农历年17 *
  • CHINESE_MONTH - 农历月18 *
  • CHINESE_DATE - 农历日19 *
  • CHINESE_SECTIONAL_TERM - 当月的节气20 *
  • CHINESE_PRINCIPLE_TERM - 当月的中气21 *
  • CHINESE_HEAVENLY_STEM - 农历年的天干22 *
  • CHINESE_EARTHLY_BRANCH - 农历年的地支23 *
  • CHINESE_ZODIAC - 农历年的属相24 *
  • CHINESE_TERM_OR_DATE - 如果当天存在一个节气则指示节气,否则如果当天是初一则指示农历月,否则指示农历日25 *
26 * 注意:
27 * 由于Calendar类的设定,公历月份从0起始。所有方法都遵循了这一约定。
28 * 但所有的农历属性从1起始。即使是在Calendar提供的方法中,农历月也是从1起始的,并以负数表示闰月。
29 * clear()方法在某些情况下会导致农历和公历日期不对应或是不能达到预期的重置效果,应尽量避免使用。
30 * 使用getSimpleDateString()获得公历日期字符串时,公历月已经修正;
31 * 使用getSimpleChineseDateString()获得农历日期字符串时,农历闰月以*表示。
32 *33 *@version0.12 2011-9-5
34 *
修复一个当使用农历正月日期初始化日历时陷入死循环的问题。
35 *@version0.11 2009-12-27
36 *
修复了获取中文农历时未计算农历日期的问题;
37 * 加入一个字段CHINESE_TERM_OR_DATE用于模仿台历的显示方式:如果当天有节气则指示节气,如果是初一指示农历月,38 * 否则指示农历日。
39 *@version0.10 2009-12-2240 */

41 public final class ChineseCalendar extendsGregorianCalendar {42 private static final long serialVersionUID = 8L;43

44 /**农历年*/

45 public static final int CHINESE_YEAR = 801;46 /**农历月*/

47 public static final int CHINESE_MONTH = 802;48 /**农历日*/

49 public static final int CHINESE_DATE = 803;50 /**当月的节气对应的公历日(前一个节气)*/

51 public static final int CHINESE_SECTIONAL_TERM = 804;52 /**当月的中气对应的公历日(后一个节气)*/

53 public static final int CHINESE_PRINCIPLE_TERM = 805;54 /**天干*/

55 public static final int CHINESE_HEAVENLY_STEM = 806;56 /**地支*/

57 public static final int CHINESE_EARTHLY_BRANCH = 807;58 /**农历年的属相(生肖)*/

59 public static final int CHINESE_ZODIAC = 808;60 /**节气或者农历日*/

61 public static final int CHINESE_TERM_OR_DATE = 888;62

63

64 //add by skywang

65 /**农历节日*/

66 public static final int LUNAR_FESTIVAL = 809;67 /**阳历节日*/

68 public static final int SOLAR_FESTIVAL = 810;69 /**节气*/

70 public static final int CHINESE_TERM = 811;71 /**月或者农历日*/

72 public static final int CHINESE_MONTH_OR_DATE = 812;73 /**节日 或 节气 或 农历日*/

74 public static final int FESTIVAL_OR_TERM_OR_DATE = 813;75

76 private intchineseYear;77 private int chineseMonth; //1起始,负数表示闰月

78 private intchineseDate;79 private int sectionalTerm; //当月节气的公历日

80 private int principleTerm; //当月中气的公历日

81

82 private boolean areChineseFieldsComputed; //农历日期是否已经经过计算确认

83 private boolean areSolarTermsComputed; //节气是否已经经过计算确认

84 private boolean lastSetChinese; //最后设置的是不是农历属性

85

86 /**使用当前时间构造一个实例。*/

87 publicChineseCalendar() {88 super();89 }90

91 /**使用指定时间构造一个实例。*/

92 publicChineseCalendar(Date d) {93 super.setTime(d);94 }95

96 /**使用指定时间构造一个实例。*/

97 publicChineseCalendar(Calendar c) {98 this(c.getTime());99 }100

101 /**使用指定公历日期构造一个实例。*/

102 public ChineseCalendar(int y, int m, intd) {103 super(y, m, d);104 }105

106 /**

107 * 使用指定日期构造一个实例。108 *109 *@paramisChinese110 * 是否为农历日期111 *@paramy112 *@paramm113 *@paramd114 */

115 public ChineseCalendar(boolean isChinese, int y, int m, intd) {116 if(isChinese) {117 set(CHINESE_YEAR, y);118 set(CHINESE_MONTH, m);119 set(CHINESE_DATE, d);120 } else{121 set(y, m, d);122 }123 }124

125 public void set(int field, intvalue) {126 computeIfNeed(field);127

128 if(isChineseField(field)) {129 //农历属性

130 switch(field) {131 caseCHINESE_YEAR:132 chineseYear =value;133 break;134 caseCHINESE_MONTH:135 chineseMonth =value;136 break;137 caseCHINESE_DATE:138 chineseDate =value;139 break;140 default:141 throw new IllegalArgumentException("不支持的field设置:" +field);142 }143 lastSetChinese = true;144 } else{145 //非农历属性

146 super.set(field, value);147 lastSetChinese = false;148 }149 areFieldsSet = false;150 areChineseFieldsComputed = false;151 areSolarTermsComputed = false;152 }153

154 public int get(intfield) {155 computeIfNeed(field);156

157 if (!isChineseField(field)) {158 return super.get(field);159 }160

161 switch(field) {162 caseCHINESE_YEAR:163 returnchineseYear;164 caseCHINESE_MONTH:165 returnchineseMonth;166 caseCHINESE_DATE:167 returnchineseDate;168 caseCHINESE_SECTIONAL_TERM:169 returnsectionalTerm;170 caseCHINESE_PRINCIPLE_TERM:171 returnprincipleTerm;172 caseCHINESE_HEAVENLY_STEM:173 return (chineseYear - 4) % 10 + 1;174 caseCHINESE_EARTHLY_BRANCH:175 caseCHINESE_ZODIAC:176 return (chineseYear - 4) % 12 + 1;177 caseCHINESE_MONTH_OR_DATE:178 if (get(CHINESE_DATE) == 1) {179 returnCHINESE_MONTH;180 } else{181 returnCHINESE_DATE;182 }183 caseCHINESE_TERM_OR_DATE:184 intoption;185 if (get(Calendar.DATE) ==get(CHINESE_SECTIONAL_TERM)) {186 option =CHINESE_SECTIONAL_TERM;187 } else if (get(Calendar.DATE) ==get(CHINESE_PRINCIPLE_TERM)) {188 option =CHINESE_PRINCIPLE_TERM;189 } else if (get(CHINESE_DATE) == 1) {190 option =CHINESE_MONTH;191 } else{192 option =CHINESE_DATE;193 }194 returnoption;195 default:196 throw new IllegalArgumentException("不支持的field获取:" +field);197 }198 }199

200 public void add(int field, intamount) {201 computeIfNeed(field);202

203 if (!isChineseField(field)) {204 super.add(field, amount);205 lastSetChinese = false;206 areChineseFieldsComputed = false;207 areSolarTermsComputed = false;208 return;209 }210

211 switch(field) {212 caseCHINESE_YEAR:213 chineseYear +=amount;214 break;215 caseCHINESE_MONTH:216 for (int i = 0; i < amount; i++) {217 chineseMonth =nextChineseMonth(chineseYear, chineseMonth);218 if (chineseMonth == 1) {219 chineseYear++;220 }221 }222 break;223 caseCHINESE_DATE:224 int maxDate =daysInChineseMonth(chineseYear, chineseMonth);225 for (int i = 0; i < amount; i++) {226 chineseDate++;227 if (chineseDate >maxDate) {228 chineseDate = 1;229 chineseMonth =nextChineseMonth(chineseYear, chineseMonth);230 if (chineseMonth == 1) {231 chineseYear++;232 }233 maxDate =daysInChineseMonth(chineseYear, chineseMonth);234 }235 }236 default:237 throw new IllegalArgumentException("不支持的field:" +field);238 }239

240 lastSetChinese = true;241 areFieldsSet = false;242 areChineseFieldsComputed = false;243 areSolarTermsComputed = false;244 }245

246 public void roll(int field, intamount) {247 computeIfNeed(field);248

249 if (!isChineseField(field)) {250 super.roll(field, amount);251 lastSetChinese = false;252 areChineseFieldsComputed = false;253 areSolarTermsComputed = false;254 return;255 }256

257 switch(field) {258 caseCHINESE_YEAR:259 chineseYear +=amount;260 break;261 caseCHINESE_MONTH:262 for (int i = 0; i < amount; i++) {263 chineseMonth =nextChineseMonth(chineseYear, chineseMonth);264 }265 break;266 caseCHINESE_DATE:267 int maxDate =daysInChineseMonth(chineseYear, chineseMonth);268 for (int i = 0; i < amount; i++) {269 chineseDate++;270 if (chineseDate >maxDate) {271 chineseDate = 1;272 }273 }274 default:275 throw new IllegalArgumentException("不支持的field:" +field);276 }277

278 lastSetChinese = true;279 areFieldsSet = false;280 areChineseFieldsComputed = false;281 areSolarTermsComputed = false;282 }283

284 /**

285 * 获得属性的中文,可以使用的属性字段为DAY_OF_WEEK以及所有农历属性字段。286 *287 *@paramfield288 *@return

289 */

290 public String getChinese(intfield) {291 computeIfNeed(field);292

293 switch(field) {294 caseCHINESE_YEAR:295 returngetChinese(CHINESE_HEAVENLY_STEM)296 + getChinese(CHINESE_EARTHLY_BRANCH) + "年";297 caseCHINESE_MONTH:298 if (chineseMonth > 0)299 return chineseMonthNames[chineseMonth] + "月";300 else

301 return "闰" + chineseMonthNames[-chineseMonth] + "月";302 caseCHINESE_DATE:303 returnchineseDateNames[chineseDate];304 caseCHINESE_SECTIONAL_TERM:305 returnsectionalTermNames[get(Calendar.MONTH)];306 caseCHINESE_PRINCIPLE_TERM:307 returnprincipleTermNames[get(Calendar.MONTH)];308 caseCHINESE_HEAVENLY_STEM:309 returnstemNames[get(field)];310 caseCHINESE_EARTHLY_BRANCH:311 returnbranchNames[get(field)];312 caseCHINESE_ZODIAC:313 returnanimalNames[get(field)];314 caseCalendar.DAY_OF_WEEK:315 returnchineseWeekNames[get(field)];316 caseCHINESE_TERM_OR_DATE:317 returngetChinese(get(CHINESE_TERM_OR_DATE));318 caseLUNAR_FESTIVAL:319 returngetLunarFestival();320 caseSOLAR_FESTIVAL:321 returngetSolarFestival();322 caseFESTIVAL_OR_TERM_OR_DATE:323 returngetFestivalOrTermOrDate();324 //TODO CHECK

325 caseCHINESE_MONTH_OR_DATE:326 returngetChinese(get(CHINESE_MONTH_OR_DATE));327 caseCHINESE_TERM:328 returngetChineseTerm();329 default:330 throw new IllegalArgumentException("不支持的field中文获取:" +field);331 }332 }333

334 publicString getSimpleGregorianDateString() {335 return new StringBuffer().append(get(YEAR)).append("-")336 .append(get(MONTH) + 1).append("-").append(get(DATE))337 .toString();338 }339

340 publicString getSimpleChineseDateString() {341 return newStringBuffer()342 .append(get(CHINESE_YEAR))343 .append("-")344 .append(get(CHINESE_MONTH) > 0 ? "" + get(CHINESE_MONTH) : "*"

345 + (-get(CHINESE_MONTH))).append("-")346 .append(get(CHINESE_DATE)).toString();347 }348

349 publicString getChineseDateString() {350 return newStringBuffer().append(getChinese(CHINESE_YEAR))351 .append(getChinese(CHINESE_MONTH))352 .append(getChinese(CHINESE_DATE)).toString();353 }354

355 publicString toString() {356 StringBuffer buf = newStringBuffer();357 buf.append(getSimpleGregorianDateString()).append(" | ")358 .append(getChinese(DAY_OF_WEEK)).append(" | [农历]")359 .append(getChineseDateString()).append(" ")360 .append(getChinese(CHINESE_ZODIAC)).append("年 ")361 .append(get(CHINESE_SECTIONAL_TERM)).append("日")362 .append(getChinese(CHINESE_SECTIONAL_TERM)).append(" ")363 .append(get(CHINESE_PRINCIPLE_TERM)).append("日")364 .append(getChinese(CHINESE_PRINCIPLE_TERM));365 returnbuf.toString();366 }367

368 /**

369 * 判断是不是农历属性370 *371 *@paramfield372 *@return

373 */

374 private boolean isChineseField(intfield) {375 switch(field) {376 caseCHINESE_YEAR:377 caseCHINESE_MONTH:378 caseCHINESE_DATE:379 caseCHINESE_SECTIONAL_TERM:380 caseCHINESE_PRINCIPLE_TERM:381 caseCHINESE_HEAVENLY_STEM:382 caseCHINESE_EARTHLY_BRANCH:383 caseCHINESE_ZODIAC:384 caseCHINESE_TERM_OR_DATE:385 caseCHINESE_MONTH_OR_DATE:386 return true;387 default:388 return false;389 }390 }391

392 /**

393 * 判断是不是与节气有关的属性394 *395 *@paramfield396 *@return

397 */

398 private boolean isChineseTermsField(intfield) {399 switch(field) {400 caseCHINESE_SECTIONAL_TERM:401 caseCHINESE_PRINCIPLE_TERM:402 caseCHINESE_TERM_OR_DATE:403 return true;404 default:405 return false;406 }407 }408

409 /**

410 * 如果上一次设置的与这次将要设置或获取的属性不是同一类(农历/公历),
411 * 例如上一次设置的是农历而现在要设置或获取公历,
412 * 则需要先根据之前设置的农历日期计算出公历日期。413 *414 *@paramfield415 */

416 private void computeIfNeed(intfield) {417 if(isChineseField(field)) {418 if (!lastSetChinese && !areChineseFieldsComputed) {419 super.complete();420 computeChineseFields();421 areFieldsSet = true;422 areChineseFieldsComputed = true;423 areSolarTermsComputed = false;424 }425 if (isChineseTermsField(field) && !areSolarTermsComputed) {426 computeSolarTerms();427 areSolarTermsComputed = true;428 }429 } else{430 if (lastSetChinese && !areFieldsSet) {431 computeGregorianFields();432 super.complete();433 areFieldsSet = true;434 areChineseFieldsComputed = true;435 areSolarTermsComputed = false;436 }437 }438 }439

440 /**

441 * 使用农历日期计算出公历日期442 */

443 private voidcomputeGregorianFields() {444 int y =chineseYear;445 int m =chineseMonth;446 int d =chineseDate;447 areChineseFieldsComputed = true;448 areFieldsSet = true;449 lastSetChinese = false;450

451 //调整日期范围

452 if (y < 1900)453 y = 1899;454 else if (y > 2100)455 y = 2101;456

457 if (m < -12)458 m = -12;459 else if (m > 12)460 m = 12;461

462 if (d < 1)463 d = 1;464 else if (d > 30)465 d = 30;466

467 int dateint = y * 10000 + Math.abs(m) * 100 +d;468 if (dateint < 19001111) { //太小

469 set(1901, Calendar.JANUARY, 1);470 super.complete();471 } else if (dateint > 21001201) { //太大

472 set(2100, Calendar.DECEMBER, 31);473 super.complete();474 } else{475 if (Math.abs(m) > 12) {476 m = 12;477 }478 int days =ChineseCalendar.daysInChineseMonth(y, m);479 if (days == 0) {480 m = -m;481 days =ChineseCalendar.daysInChineseMonth(y, m);482 }483 if (d >days) {484 d =days;485 }486 set(y, Math.abs(m) - 1, d);487 computeChineseFields();488

489 int amount = 0;490 while (chineseYear != y || chineseMonth !=m) {491 amount +=daysInChineseMonth(chineseYear, chineseMonth);492 chineseMonth =nextChineseMonth(chineseYear, chineseMonth);493 if (chineseMonth == 1) {494 chineseYear++;495 }496 }497 amount += d -chineseDate;498

499 super.add(Calendar.DATE, amount);500 }501 computeChineseFields();502 }503

504 /**

505 * 使用公历日期计算出农历日期506 */

507 private voidcomputeChineseFields() {508 int gregorianYear =internalGet(Calendar.YEAR);509 int gregorianMonth = internalGet(Calendar.MONTH) + 1;510 int gregorianDate =internalGet(Calendar.DATE);511

512 if (gregorianYear < 1901 || gregorianYear > 2100) {513 return;514 }515

516 intstartYear, startMonth, startDate;517 if (gregorianYear < 2000) {518 startYear =baseYear;519 startMonth =baseMonth;520 startDate =baseDate;521 chineseYear =baseChineseYear;522 chineseMonth =baseChineseMonth;523 chineseDate =baseChineseDate;524 } else{525 //第二个对应日,用以提高计算效率526 //公历 2000 年 1 月 1 日,对应农历 4697(1999) 年 11 月 25 日

527 startYear = baseYear + 99;528 startMonth = 1;529 startDate = 1;530 chineseYear = baseChineseYear + 99;531 chineseMonth = 11;532 chineseDate = 25;533 }534

535 int daysDiff = 0;536

537 //年

538 for (int i = startYear; i < gregorianYear; i++) {539 if(isGregorianLeapYear(i)) {540 daysDiff += 366; //leap year

541 } else{542 daysDiff += 365;543 }544 }545

546 //月

547 for (int i = startMonth; i < gregorianMonth; i++) {548 daysDiff += daysInGregorianMonth(gregorianYear, i - 1);549 }550

551 //日

552 daysDiff += gregorianDate -startDate;553

554 chineseDate +=daysDiff;555

556 int lastDate =daysInChineseMonth(chineseYear, chineseMonth);557 while (chineseDate >lastDate) {558 chineseDate -=lastDate;559 chineseMonth =nextChineseMonth(chineseYear, chineseMonth);560 if (chineseMonth == 1) {561 chineseYear++;562 }563 lastDate =daysInChineseMonth(chineseYear, chineseMonth);564 }565

566 }567

568 /**

569 * 计算节气570 */

571 private voidcomputeSolarTerms() {572 int gregorianYear =internalGet(Calendar.YEAR);573 int gregorianMonth =internalGet(Calendar.MONTH);574

575 if (gregorianYear < 1901 || gregorianYear > 2100) {576 return;577 }578 sectionalTerm =sectionalTerm(gregorianYear, gregorianMonth);579 principleTerm =principleTerm(gregorianYear, gregorianMonth);580 }581

582 /*接下来是静态方法~*/

583 /**

584 * 是否为公历闰年585 *586 *@paramyear587 *@return

588 */

589 public static boolean isGregorianLeapYear(intyear) {590 boolean isLeap = false;591 if (year % 4 == 0) {592 isLeap = true;593 }594 if (year % 100 == 0) {595 isLeap = false;596 }597 if (year % 400 == 0) {598 isLeap = true;599 }600 returnisLeap;601 }602

603 /**

604 * 计算公历年的当月天数,公历月从0起始!605 *606 *@paramy607 *@paramm608 *@return

609 */

610 public static int daysInGregorianMonth(int y, intm) {611 int d =daysInGregorianMonth[m];612 if (m == Calendar.FEBRUARY &&isGregorianLeapYear(y)) {613 d++; //公历闰年二月多一天

614 }615 returnd;616 }617

618 /**

619 * 计算公历年当月的节气,公历月从0起始!620 *621 *@paramy622 *@paramm623 *@return

624 */

625 public static int sectionalTerm(int y, intm) {626 m++;627 if (y < 1901 || y > 2100) {628 return 0;629 }630 int index = 0;631 int ry = y - baseYear + 1;632 while (ry >= sectionalTermYear[m - 1][index]) {633 index++;634 }635 int term = sectionalTermMap[m - 1][4 * index + ry % 4];636 if ((ry == 121) && (m == 4)) {637 term = 5;638 }639 if ((ry == 132) && (m == 4)) {640 term = 5;641 }642 if ((ry == 194) && (m == 6)) {643 term = 6;644 }645 returnterm;646 }647

648 /**

649 * 计算公历年当月的中气,公历月从0起始!650 *651 *@paramy652 *@paramm653 *@return

654 */

655 public static int principleTerm(int y, intm) {656 m++;657 if (y < 1901 || y > 2100) {658 return 0;659 }660 int index = 0;661 int ry = y - baseYear + 1;662 while (ry >= principleTermYear[m - 1][index]) {663 index++;664 }665 int term = principleTermMap[m - 1][4 * index + ry % 4];666 if ((ry == 171) && (m == 3)) {667 term = 21;668 }669 if ((ry == 181) && (m == 5)) {670 term = 21;671 }672 returnterm;673 }674

675 /**

676 * 计算农历年的天数677 *678 *@paramy679 *@paramm680 *@return

681 */

682 public static int daysInChineseMonth(int y, intm) {683 //注意:闰月 m < 0

684 int index = y - baseChineseYear +baseIndex;685 int v = 0;686 int l = 0;687 int d = 30;688 if (1 <= m && m <= 8) {689 v = chineseMonths[2 *index];690 l = m - 1;691 if (((v >> l) & 0x01) == 1) {692 d = 29;693 }694 } else if (9 <= m && m <= 12) {695 v = chineseMonths[2 * index + 1];696 l = m - 9;697 if (((v >> l) & 0x01) == 1) {698 d = 29;699 }700 } else{701 v = chineseMonths[2 * index + 1];702 v = (v >> 4) & 0x0F;703 if (v !=Math.abs(m)) {704 d = 0;705 } else{706 d = 29;707 for (int i = 0; i < bigLeapMonthYears.length; i++) {708 if (bigLeapMonthYears[i] ==index) {709 d = 30;710 break;711 }712 }713 }714 }715 returnd;716 }717

718 /**

719 * 计算农历的下个月720 *721 *@paramy722 *@paramm723 *@return

724 */

725 public static int nextChineseMonth(int y, intm) {726 int n = Math.abs(m) + 1;727 if (m > 0) {728 int index = y - baseChineseYear +baseIndex;729 int v = chineseMonths[2 * index + 1];730 v = (v >> 4) & 0x0F;731 if (v ==m) {732 n = -m;733 }734 }735 if (n == 13) {736 n = 1;737 }738 returnn;739 }740

741 /*日历第一天的日期*/

742 private static final int baseYear = 1901;743 private static final int baseMonth = 1;744 private static final int baseDate = 1;745 private static final int baseIndex = 0;746 private static final int baseChineseYear = 1900;747 private static final int baseChineseMonth = 11;748 private static final int baseChineseDate = 11;749

750 /*中文字符串*/

751 private static final String[] chineseWeekNames = { "", "星期日", "星期一", "星期二",752 "星期三", "星期四", "星期五", "星期六"};753 private static final String[] chineseMonthNames = { "", "正", "二", "三", "四",754 "五", "六", "七", "八", "九", "十", "十一", "十二"};755 private static final String[] chineseDateNames = { "", "初一", "初二", "初三",756 "初四", "初五", "初六", "初七", "初八", "初九", "初十", "十一", "十二", "十三", "十四",757 "十五", "十六", "十七", "十八", "十九", "二十", "廿一", "廿二", "廿三", "廿四", "廿五",758 "廿六", "廿七", "廿八", "廿九", "三十"};759 private static final String[] principleTermNames = { "大寒", "雨水", "春分",760 "谷雨", "夏满", "夏至", "大暑", "处暑", "秋分", "霜降", "小雪", "冬至"};761 private static final String[] sectionalTermNames = { "小寒", "立春", "惊蛰",762 "清明", "立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪"};763 private static final String[] stemNames = { "", "甲", "乙", "丙", "丁", "戊",764 "己", "庚", "辛", "壬", "癸"};765 private static final String[] branchNames = { "", "子", "丑", "寅", "卯", "辰",766 "巳", "午", "未", "申", "酉", "戌", "亥"};767 private static final String[] animalNames = { "", "鼠", "牛", "虎", "兔", "龙",768 "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};769

770 /*接下来是数据压缩表~*/

771 private static final int[] bigLeapMonthYears = { 6, 14, 19, 25, 33, 36, 38,772 41, 44, 52, 55, 79, 117, 136, 147, 150, 155, 158, 185, 193};773 private static final char[][] sectionalTermMap ={774 { 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5,775 5, 5, 5, 4, 5, 5},776 { 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3,777 3, 4, 4, 3, 3, 3},778 { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,779 5, 5, 4, 5, 5, 5, 5},780 { 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4,781 4, 5, 4, 4, 4, 4, 5},782 { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5,783 5, 5, 4, 5, 5, 5, 5},784 { 6, 6, 7, 7, 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5,785 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5},786 { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,787 7, 7, 6, 6, 6, 7, 7},788 { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,789 7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7},790 { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7,791 7, 7, 6, 7, 7, 7, 7},792 { 9, 9, 9, 9, 8, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 9, 8, 8, 8, 8, 7, 8,793 8, 8, 7, 7, 8, 8, 8},794 { 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7,795 7, 7, 6, 6, 7, 7, 7},796 { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6,797 7, 7, 6, 6, 6, 7, 7} };798 private static final char[][] sectionalTermYear ={799 { 13, 49, 85, 117, 149, 185, 201, 250, 250},800 { 13, 45, 81, 117, 149, 185, 201, 250, 250},801 { 13, 48, 84, 112, 148, 184, 200, 201, 250},802 { 13, 45, 76, 108, 140, 172, 200, 201, 250},803 { 13, 44, 72, 104, 132, 168, 200, 201, 250},804 { 5, 33, 68, 96, 124, 152, 188, 200, 201},805 { 29, 57, 85, 120, 148, 176, 200, 201, 250},806 { 13, 48, 76, 104, 132, 168, 196, 200, 201},807 { 25, 60, 88, 120, 148, 184, 200, 201, 250},808 { 16, 44, 76, 108, 144, 172, 200, 201, 250},809 { 28, 60, 92, 124, 160, 192, 200, 201, 250},810 { 17, 53, 85, 124, 156, 188, 200, 201, 250} };811 private static final char[][] principleTermMap ={812 { 21, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20,813 20, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20},814 { 20, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, 19, 19,815 19, 18, 18, 19, 19, 18, 18, 18, 18, 18, 18, 18},816 { 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21,817 20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 20},818 { 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20,819 19, 20, 20, 20, 19, 19, 20, 20, 19, 19, 19, 20, 20},820 { 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21,821 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 21},822 { 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22,823 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 21},824 { 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23,825 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 23},826 { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,827 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23},828 { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23,829 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23},830 { 24, 24, 24, 24, 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24,831 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 23},832 { 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23,833 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 22},834 { 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22,835 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 22} };836 private static final char[][] principleTermYear ={837 { 13, 45, 81, 113, 149, 185, 201},838 { 21, 57, 93, 125, 161, 193, 201},839 { 21, 56, 88, 120, 152, 188, 200, 201},840 { 21, 49, 81, 116, 144, 176, 200, 201},841 { 17, 49, 77, 112, 140, 168, 200, 201},842 { 28, 60, 88, 116, 148, 180, 200, 201},843 { 25, 53, 84, 112, 144, 172, 200, 201},844 { 29, 57, 89, 120, 148, 180, 200, 201},845 { 17, 45, 73, 108, 140, 168, 200, 201},846 { 28, 60, 92, 124, 160, 192, 200, 201},847 { 16, 44, 80, 112, 148, 180, 200, 201},848 { 17, 53, 88, 120, 156, 188, 200, 201} };849

850 private static final char[] daysInGregorianMonth = { 31, 28, 31, 30, 31,851 30, 31, 31, 30, 31, 30, 31};852 private static final char[] chineseMonths = { 0x00, 0x04, 0xad, 0x08, 0x5a,853 0x01, 0xd5, 0x54, 0xb4, 0x09, 0x64, 0x05, 0x59, 0x45, 0x95, 0x0a,854 0xa6, 0x04, 0x55, 0x24, 0xad, 0x08, 0x5a, 0x62, 0xda, 0x04, 0xb4,855 0x05, 0xb4, 0x55, 0x52, 0x0d, 0x94, 0x0a, 0x4a, 0x2a, 0x56, 0x02,856 0x6d, 0x71, 0x6d, 0x01, 0xda, 0x02, 0xd2, 0x52, 0xa9, 0x05, 0x49,857 0x0d, 0x2a, 0x45, 0x2b, 0x09, 0x56, 0x01, 0xb5, 0x20, 0x6d, 0x01,858 0x59, 0x69, 0xd4, 0x0a, 0xa8, 0x05, 0xa9, 0x56, 0xa5, 0x04, 0x2b,859 0x09, 0x9e, 0x38, 0xb6, 0x08, 0xec, 0x74, 0x6c, 0x05, 0xd4, 0x0a,860 0xe4, 0x6a, 0x52, 0x05, 0x95, 0x0a, 0x5a, 0x42, 0x5b, 0x04, 0xb6,861 0x04, 0xb4, 0x22, 0x6a, 0x05, 0x52, 0x75, 0xc9, 0x0a, 0x52, 0x05,862 0x35, 0x55, 0x4d, 0x0a, 0x5a, 0x02, 0x5d, 0x31, 0xb5, 0x02, 0x6a,863 0x8a, 0x68, 0x05, 0xa9, 0x0a, 0x8a, 0x6a, 0x2a, 0x05, 0x2d, 0x09,864 0xaa, 0x48, 0x5a, 0x01, 0xb5, 0x09, 0xb0, 0x39, 0x64, 0x05, 0x25,865 0x75, 0x95, 0x0a, 0x96, 0x04, 0x4d, 0x54, 0xad, 0x04, 0xda, 0x04,866 0xd4, 0x44, 0xb4, 0x05, 0x54, 0x85, 0x52, 0x0d, 0x92, 0x0a, 0x56,867 0x6a, 0x56, 0x02, 0x6d, 0x02, 0x6a, 0x41, 0xda, 0x02, 0xb2, 0xa1,868 0xa9, 0x05, 0x49, 0x0d, 0x0a, 0x6d, 0x2a, 0x09, 0x56, 0x01, 0xad,869 0x50, 0x6d, 0x01, 0xd9, 0x02, 0xd1, 0x3a, 0xa8, 0x05, 0x29, 0x85,870 0xa5, 0x0c, 0x2a, 0x09, 0x96, 0x54, 0xb6, 0x08, 0x6c, 0x09, 0x64,871 0x45, 0xd4, 0x0a, 0xa4, 0x05, 0x51, 0x25, 0x95, 0x0a, 0x2a, 0x72,872 0x5b, 0x04, 0xb6, 0x04, 0xac, 0x52, 0x6a, 0x05, 0xd2, 0x0a, 0xa2,873 0x4a, 0x4a, 0x05, 0x55, 0x94, 0x2d, 0x0a, 0x5a, 0x02, 0x75, 0x61,874 0xb5, 0x02, 0x6a, 0x03, 0x61, 0x45, 0xa9, 0x0a, 0x4a, 0x05, 0x25,875 0x25, 0x2d, 0x09, 0x9a, 0x68, 0xda, 0x08, 0xb4, 0x09, 0xa8, 0x59,876 0x54, 0x03, 0xa5, 0x0a, 0x91, 0x3a, 0x96, 0x04, 0xad, 0xb0, 0xad,877 0x04, 0xda, 0x04, 0xf4, 0x62, 0xb4, 0x05, 0x54, 0x0b, 0x44, 0x5d,878 0x52, 0x0a, 0x95, 0x04, 0x55, 0x22, 0x6d, 0x02, 0x5a, 0x71, 0xda,879 0x02, 0xaa, 0x05, 0xb2, 0x55, 0x49, 0x0b, 0x4a, 0x0a, 0x2d, 0x39,880 0x36, 0x01, 0x6d, 0x80, 0x6d, 0x01, 0xd9, 0x02, 0xe9, 0x6a, 0xa8,881 0x05, 0x29, 0x0b, 0x9a, 0x4c, 0xaa, 0x08, 0xb6, 0x08, 0xb4, 0x38,882 0x6c, 0x09, 0x54, 0x75, 0xd4, 0x0a, 0xa4, 0x05, 0x45, 0x55, 0x95,883 0x0a, 0x9a, 0x04, 0x55, 0x44, 0xb5, 0x04, 0x6a, 0x82, 0x6a, 0x05,884 0xd2, 0x0a, 0x92, 0x6a, 0x4a, 0x05, 0x55, 0x0a, 0x2a, 0x4a, 0x5a,885 0x02, 0xb5, 0x02, 0xb2, 0x31, 0x69, 0x03, 0x31, 0x73, 0xa9, 0x0a,886 0x4a, 0x05, 0x2d, 0x55, 0x2d, 0x09, 0x5a, 0x01, 0xd5, 0x48, 0xb4,887 0x09, 0x68, 0x89, 0x54, 0x0b, 0xa4, 0x0a, 0xa5, 0x6a, 0x95, 0x04,888 0xad, 0x08, 0x6a, 0x44, 0xda, 0x04, 0x74, 0x05, 0xb0, 0x25, 0x54,889 0x03};890

891 privateString getChineseTerm() {892 if (get(Calendar.DATE) ==get(CHINESE_SECTIONAL_TERM)) {893 returnsectionalTermNames[get(Calendar.MONTH)];894 } else if (get(Calendar.DATE) ==get(CHINESE_PRINCIPLE_TERM)) {895 returnprincipleTermNames[get(Calendar.MONTH)];896 } else

897 return null;898 }899 //add by skywang

900 privateString getLunarFestival() {901 int day =get(CHINESE_DATE);902 int month =get(CHINESE_MONTH);903 String sToday = day < 10 ? "0" + day:"" +day;904 String sMonth = month<10 ? "0" +(month):""+(month);905

906 return lFestival.get(sMonth+sToday);907 }908 privateString getSolarFestival() {909 int day =get(Calendar.DATE);910 int month =get(Calendar.MONTH);911 String sToday = day < 10 ? "0" + day:"" +day;912 String sMonth = month<10 ? "0" +(month+1):""+(month+1);913

914 return sFestival.get(sMonth+sToday);915 }916 privateString getFestivalOrTermOrDate() {917 String ret;918 if ((ret = getSolarFestival()) != null)919 returnret;920 if ((ret = getLunarFestival()) != null)921 returnret;922 returngetChinese(get(CHINESE_TERM_OR_DATE));923 }924

925

926 //公历节日

927 private static HashMap sFestival =new HashMap();928 //农历介入

929 private static HashMap lFestival =new HashMap();930 static{931 sFestival.put("0101","元旦");932 sFestival.put("0214","情人节");933 sFestival.put("0308","妇女节");934 sFestival.put("0312","植树节");935 sFestival.put("0401","愚人节");936 sFestival.put("0501","劳动节");937 sFestival.put("0504","青年节");938 sFestival.put("0601","儿童节");939 sFestival.put("0701","建党节");940 sFestival.put("0801","建军节");941 sFestival.put("0910","教师节");942 sFestival.put("1001","国庆节");943 sFestival.put("1031","万圣节");944 //sFestival.put("1112","孙中山诞辰");

945 sFestival.put("1225","圣诞节");946

947 lFestival.put("0101","春节");948 //lFestival.put("0102","大年初二");949 //lFestival.put("0103","大年初三");

950 lFestival.put("0115","元宵节");951 lFestival.put("0505","端午节");952 lFestival.put("0707","七夕");953 lFestival.put("0815","中秋节");954 lFestival.put("0909","重阳节");955 lFestival.put("1208","腊八节");956 //lFestival.put("1299","除夕");

957 }958 }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/1017308
推荐阅读
相关标签
  

闽ICP备14008679号