/* */ package com.ibm.icu.util;
/* */
/* */ import com.ibm.icu.impl.CalendarAstronomer;
/* */ import com.ibm.icu.impl.CalendarCache;
/* */ import com.ibm.icu.text.ChineseDateFormat;
/* */ import com.ibm.icu.text.DateFormat;
/* */ import java.io.IOException;
/* */ import java.io.ObjectInputStream;
/* */ import java.util.Date;
/* */ import java.util.Locale;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public class ChineseCalendar
/* */ extends Calendar
/* */ {
/* */ private static final long serialVersionUID = 7312110751940929420L;
/* 110 */ private transient CalendarAstronomer astro = new CalendarAstronomer();
/* */
/* */
/* */
/* */
/* */
/* 116 */ private transient CalendarCache winterSolsticeCache = new CalendarCache();
/* */
/* */
/* */
/* */
/* */
/* 122 */ private transient CalendarCache newYearCache = new CalendarCache();
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private transient boolean isLeapYear;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar()
/* */ {
/* 141 */ setTimeInMillis(System.currentTimeMillis());
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(Date date)
/* */ {
/* 152 */ setTime(date);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(int year, int month, int isLeapMonth, int date)
/* */ {
/* 169 */ super(TimeZone.getDefault(), ULocale.getDefault(ULocale.Category.FORMAT));
/* */
/* */
/* */
/* 173 */ setTimeInMillis(System.currentTimeMillis());
/* */
/* 175 */ set(21, 0);
/* */
/* */
/* 178 */ set(1, year);
/* 179 */ set(2, month);
/* 180 */ set(22, isLeapMonth);
/* 181 */ set(5, date);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(int year, int month, int isLeapMonth, int date, int hour, int minute, int second)
/* */ {
/* 206 */ super(TimeZone.getDefault(), ULocale.getDefault(ULocale.Category.FORMAT));
/* */
/* */
/* */
/* 210 */ setTimeInMillis(System.currentTimeMillis());
/* */
/* 212 */ set(14, 0);
/* */
/* */
/* 215 */ set(1, year);
/* 216 */ set(2, month);
/* 217 */ set(22, isLeapMonth);
/* 218 */ set(5, date);
/* 219 */ set(11, hour);
/* 220 */ set(12, minute);
/* 221 */ set(13, second);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(int era, int year, int month, int isLeapMonth, int date)
/* */ {
/* 241 */ super(TimeZone.getDefault(), ULocale.getDefault(ULocale.Category.FORMAT));
/* */
/* */
/* */
/* 245 */ setTimeInMillis(System.currentTimeMillis());
/* */
/* */
/* 248 */ set(21, 0);
/* */
/* */
/* 251 */ set(0, era);
/* 252 */ set(1, year);
/* 253 */ set(2, month);
/* 254 */ set(22, isLeapMonth);
/* 255 */ set(5, date);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(int era, int year, int month, int isLeapMonth, int date, int hour, int minute, int second)
/* */ {
/* 282 */ super(TimeZone.getDefault(), ULocale.getDefault(ULocale.Category.FORMAT));
/* */
/* */
/* */
/* 286 */ setTimeInMillis(System.currentTimeMillis());
/* */
/* */
/* 289 */ set(14, 0);
/* */
/* */
/* 292 */ set(0, era);
/* 293 */ set(1, year);
/* 294 */ set(2, month);
/* 295 */ set(22, isLeapMonth);
/* 296 */ set(5, date);
/* 297 */ set(11, hour);
/* 298 */ set(12, minute);
/* 299 */ set(13, second);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(Locale aLocale)
/* */ {
/* 309 */ this(TimeZone.getDefault(), aLocale);
/* 310 */ setTimeInMillis(System.currentTimeMillis());
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(TimeZone zone)
/* */ {
/* 321 */ super(zone, ULocale.getDefault(ULocale.Category.FORMAT));
/* 322 */ setTimeInMillis(System.currentTimeMillis());
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(TimeZone zone, Locale aLocale)
/* */ {
/* 333 */ super(zone, aLocale);
/* 334 */ setTimeInMillis(System.currentTimeMillis());
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(ULocale locale)
/* */ {
/* 345 */ this(TimeZone.getDefault(), locale);
/* 346 */ setTimeInMillis(System.currentTimeMillis());
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public ChineseCalendar(TimeZone zone, ULocale locale)
/* */ {
/* 357 */ super(zone, locale);
/* 358 */ setTimeInMillis(System.currentTimeMillis());
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 413 */ private static final int[][] LIMITS = { { 1, 1, 83333, 83333 }, { 1, 1, 60, 60 }, { 0, 0, 11, 11 }, { 1, 1, 50, 55 }, new int[0], { 1, 1, 29, 30 }, { 1, 1, 353, 385 }, new int[0], { -1, -1, 5, 5 }, new int[0], new int[0], new int[0], new int[0], new int[0], new int[0], new int[0], new int[0], { -5000000, -5000000, 5000000, 5000000 }, new int[0], { -5000000, -5000000, 5000000, 5000000 }, new int[0], new int[0], { 0, 0, 1, 1 } };
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ protected int handleGetLimit(int field, int limitType)
/* */ {
/* 446 */ return LIMITS[field][limitType];
/* */ }
/* */
/* */
/* */
/* */ protected int handleGetExtendedYear()
/* */ {
/* */ int year;
/* */
/* */
/* */ int year;
/* */
/* 458 */ if (newestStamp(0, 1, 0) <= getStamp(19)) {
/* 459 */ year = internalGet(19, 1);
/* */ } else {
/* 461 */ int cycle = internalGet(0, 1) - 1;
/* 462 */ year = cycle * 60 + internalGet(1, 1);
/* */ }
/* 464 */ return year;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ protected int handleGetMonthLength(int extendedYear, int month)
/* */ {
/* 476 */ int thisStart = handleComputeMonthStart(extendedYear, month, true) - 2440588 + 1;
/* */
/* 478 */ int nextStart = newMoonNear(thisStart + 25, true);
/* 479 */ return nextStart - thisStart;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ protected DateFormat handleGetDateFormat(String pattern, String override, ULocale locale)
/* */ {
/* 499 */ return new ChineseDateFormat(pattern, override, locale);
/* */ }
/* */
/* */
/* */
/* */
/* 505 */ static final int[][][] CHINESE_DATE_PRECEDENCE = { { { 5 }, { 3, 7 }, { 4, 7 }, { 8, 7 }, { 3, 18 }, { 4, 18 }, { 8, 18 }, { 6 }, { 37, 22 } }, { { 3 }, { 4 }, { 8 }, { 40, 7 }, { 40, 18 } } };
/* */
/* */
/* */
/* */
/* */
/* */ private static final int CHINESE_EPOCH_YEAR = -2636;
/* */
/* */
/* */
/* */
/* */
/* */ private static final long CHINA_OFFSET = 28800000L;
/* */
/* */
/* */
/* */
/* */
/* */ private static final int SYNODIC_GAP = 25;
/* */
/* */
/* */
/* */
/* */
/* */
/* */ protected int[][][] getFieldResolutionTable()
/* */ {
/* 532 */ return CHINESE_DATE_PRECEDENCE;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private void offsetMonth(int newMoon, int dom, int delta)
/* */ {
/* 548 */ newMoon += (int)(29.530588853D * (delta - 0.5D));
/* */
/* */
/* 551 */ newMoon = newMoonNear(newMoon, true);
/* */
/* */
/* 554 */ int jd = newMoon + 2440588 - 1 + dom;
/* */
/* */
/* */
/* 558 */ if (dom > 29) {
/* 559 */ set(20, jd - 1);
/* */
/* */
/* */
/* */
/* 564 */ complete();
/* 565 */ if (getActualMaximum(5) >= dom) {
/* 566 */ set(20, jd);
/* */ }
/* */ } else {
/* 569 */ set(20, jd);
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */ public void add(int field, int amount)
/* */ {
/* 578 */ switch (field) {
/* */ case 2:
/* 580 */ if (amount != 0) {
/* 581 */ int dom = get(5);
/* 582 */ int day = get(20) - 2440588;
/* 583 */ int moon = day - dom + 1;
/* 584 */ offsetMonth(moon, dom, amount); }
/* 585 */ break;
/* */
/* */ default:
/* 588 */ super.add(field, amount);
/* */ }
/* */
/* */ }
/* */
/* */
/* */
/* */
/* */ public void roll(int field, int amount)
/* */ {
/* 598 */ switch (field) {
/* */ case 2:
/* 600 */ if (amount != 0) {
/* 601 */ int dom = get(5);
/* 602 */ int day = get(20) - 2440588;
/* 603 */ int moon = day - dom + 1;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 611 */ int m = get(2);
/* 612 */ if (this.isLeapYear) {
/* 613 */ if (get(22) == 1) {
/* 614 */ m++;
/* */
/* */
/* */
/* */ }
/* */ else
/* */ {
/* */
/* */
/* 623 */ int moon1 = moon - (int)(29.530588853D * (m - 0.5D));
/* */
/* 625 */ moon1 = newMoonNear(moon1, true);
/* 626 */ if (isLeapMonthBetween(moon1, moon)) {
/* 627 */ m++;
/* */ }
/* */ }
/* */ }
/* */
/* */
/* */
/* 634 */ int n = this.isLeapYear ? 13 : 12;
/* 635 */ int newM = (m + amount) % n;
/* 636 */ if (newM < 0) {
/* 637 */ newM += n;
/* */ }
/* */
/* 640 */ if (newM != m)
/* 641 */ offsetMonth(moon, dom, newM - m);
/* */ }
/* 643 */ break;
/* */
/* */ default:
/* 646 */ super.roll(field, amount);
/* */ }
/* */
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private static final long daysToMillis(int days)
/* */ {
/* 683 */ return days * 86400000L - 28800000L;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */ private static final int millisToDays(long millis)
/* */ {
/* 692 */ return (int)floorDivide(millis + 28800000L, 86400000L);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private int winterSolstice(int gyear)
/* */ {
/* 709 */ long cacheValue = this.winterSolsticeCache.get(gyear);
/* */
/* 711 */ if (cacheValue == CalendarCache.EMPTY)
/* */ {
/* */
/* */
/* */
/* 716 */ long ms = daysToMillis(computeGregorianMonthStart(gyear, 11) + 1 - 2440588);
/* */
/* 718 */ this.astro.setTime(ms);
/* */
/* */
/* 721 */ long solarLong = this.astro.getSunTime(CalendarAstronomer.WINTER_SOLSTICE, true);
/* */
/* 723 */ cacheValue = millisToDays(solarLong);
/* 724 */ this.winterSolsticeCache.put(gyear, cacheValue);
/* */ }
/* 726 */ return (int)cacheValue;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private int newMoonNear(int days, boolean after)
/* */ {
/* 740 */ this.astro.setTime(daysToMillis(days));
/* 741 */ long newMoon = this.astro.getMoonTime(CalendarAstronomer.NEW_MOON, after);
/* */
/* 743 */ return millisToDays(newMoon);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private int synodicMonthsBetween(int day1, int day2)
/* */ {
/* 754 */ return (int)Math.round((day2 - day1) / 29.530588853D);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private int majorSolarTerm(int days)
/* */ {
/* 765 */ this.astro.setTime(daysToMillis(days));
/* */
/* */
/* 768 */ int term = ((int)Math.floor(6.0D * this.astro.getSunLongitude() / 3.141592653589793D) + 2) % 12;
/* 769 */ if (term < 1) {
/* 770 */ term += 12;
/* */ }
/* 772 */ return term;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private boolean hasNoMajorSolarTerm(int newMoon)
/* */ {
/* 782 */ int mst = majorSolarTerm(newMoon);
/* 783 */ int nmn = newMoonNear(newMoon + 25, true);
/* 784 */ int mstt = majorSolarTerm(nmn);
/* 785 */ return mst == mstt;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private boolean isLeapMonthBetween(int newMoon1, int newMoon2)
/* */ {
/* 809 */ if (synodicMonthsBetween(newMoon1, newMoon2) >= 50) {
/* 810 */ throw new IllegalArgumentException("isLeapMonthBetween(" + newMoon1 + ", " + newMoon2 + "): Invalid parameters");
/* */ }
/* */
/* */
/* */
/* 815 */ return (newMoon2 >= newMoon1) && ((isLeapMonthBetween(newMoon1, newMoonNear(newMoon2 - 25, false))) || (hasNoMajorSolarTerm(newMoon2)));
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ protected void handleComputeFields(int julianDay)
/* */ {
/* 840 */ computeChineseFields(julianDay - 2440588, getGregorianYear(), getGregorianMonth(), true);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private void computeChineseFields(int days, int gyear, int gmonth, boolean setAllFields)
/* */ {
/* 869 */ int solsticeAfter = winterSolstice(gyear);
/* 870 */ int solsticeBefore; int solsticeBefore; if (days < solsticeAfter) {
/* 871 */ solsticeBefore = winterSolstice(gyear - 1);
/* */ } else {
/* 873 */ solsticeBefore = solsticeAfter;
/* 874 */ solsticeAfter = winterSolstice(gyear + 1);
/* */ }
/* */
/* */
/* */
/* */
/* 880 */ int firstMoon = newMoonNear(solsticeBefore + 1, true);
/* 881 */ int lastMoon = newMoonNear(solsticeAfter + 1, false);
/* 882 */ int thisMoon = newMoonNear(days + 1, false);
/* */
/* 884 */ this.isLeapYear = (synodicMonthsBetween(firstMoon, lastMoon) == 12);
/* */
/* 886 */ int month = synodicMonthsBetween(firstMoon, thisMoon);
/* 887 */ if ((this.isLeapYear) && (isLeapMonthBetween(firstMoon, thisMoon))) {
/* 888 */ month--;
/* */ }
/* 890 */ if (month < 1) {
/* 891 */ month += 12;
/* */ }
/* */
/* 894 */ boolean isLeapMonth = (this.isLeapYear) && (hasNoMajorSolarTerm(thisMoon)) && (!isLeapMonthBetween(firstMoon, newMoonNear(thisMoon - 25, false)));
/* */
/* */
/* */
/* 898 */ internalSet(2, month - 1);
/* 899 */ internalSet(22, isLeapMonth ? 1 : 0);
/* */
/* 901 */ if (setAllFields)
/* */ {
/* 903 */ int year = gyear - 62900;
/* 904 */ if ((month < 11) || (gmonth >= 6))
/* */ {
/* 906 */ year++;
/* */ }
/* 908 */ int dayOfMonth = days - thisMoon + 1;
/* */
/* 910 */ internalSet(19, year);
/* */
/* */
/* 913 */ int[] yearOfCycle = new int[1];
/* 914 */ int cycle = floorDivide(year - 1, 60, yearOfCycle);
/* 915 */ internalSet(0, cycle + 1);
/* 916 */ internalSet(1, yearOfCycle[0] + 1);
/* */
/* 918 */ internalSet(5, dayOfMonth);
/* */
/* */
/* */
/* */
/* */
/* 924 */ int newYear = newYear(gyear);
/* 925 */ if (days < newYear) {
/* 926 */ newYear = newYear(gyear - 1);
/* */ }
/* 928 */ internalSet(6, days - newYear + 1);
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private int newYear(int gyear)
/* */ {
/* 944 */ long cacheValue = this.newYearCache.get(gyear);
/* */
/* 946 */ if (cacheValue == CalendarCache.EMPTY)
/* */ {
/* 948 */ int solsticeBefore = winterSolstice(gyear - 1);
/* 949 */ int solsticeAfter = winterSolstice(gyear);
/* 950 */ int newMoon1 = newMoonNear(solsticeBefore + 1, true);
/* 951 */ int newMoon2 = newMoonNear(newMoon1 + 25, true);
/* 952 */ int newMoon11 = newMoonNear(solsticeAfter + 1, false);
/* */
/* 954 */ if ((synodicMonthsBetween(newMoon1, newMoon11) == 12) && ((hasNoMajorSolarTerm(newMoon1)) || (hasNoMajorSolarTerm(newMoon2))))
/* */ {
/* 956 */ cacheValue = newMoonNear(newMoon2 + 25, true);
/* */ } else {
/* 958 */ cacheValue = newMoon2;
/* */ }
/* */
/* 961 */ this.newYearCache.put(gyear, cacheValue);
/* */ }
/* 963 */ return (int)cacheValue;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ protected int handleComputeMonthStart(int eyear, int month, boolean useMonth)
/* */ {
/* 983 */ if ((month < 0) || (month > 11)) {
/* 984 */ int[] rem = new int[1];
/* 985 */ eyear += floorDivide(month, 12, rem);
/* 986 */ month = rem[0];
/* */ }
/* */
/* 989 */ int gyear = eyear + 62900 - 1;
/* 990 */ int newYear = newYear(gyear);
/* 991 */ int newMoon = newMoonNear(newYear + month * 29, true);
/* */
/* 993 */ int julianDay = newMoon + 2440588;
/* */
/* */
/* 996 */ int saveMonth = internalGet(2);
/* 997 */ int saveIsLeapMonth = internalGet(22);
/* */
/* */
/* 1000 */ int isLeapMonth = useMonth ? saveIsLeapMonth : 0;
/* */
/* 1002 */ computeGregorianFields(julianDay);
/* */
/* */
/* 1005 */ computeChineseFields(newMoon, getGregorianYear(), getGregorianMonth(), false);
/* */
/* */
/* 1008 */ if ((month != internalGet(2)) || (isLeapMonth != internalGet(22)))
/* */ {
/* 1010 */ newMoon = newMoonNear(newMoon + 25, true);
/* 1011 */ julianDay = newMoon + 2440588;
/* */ }
/* */
/* 1014 */ internalSet(2, saveMonth);
/* 1015 */ internalSet(22, saveIsLeapMonth);
/* */
/* 1017 */ return julianDay - 1;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */ public String getType()
/* */ {
/* 1026 */ return "chinese";
/* */ }
/* */
/* */
/* */
/* */
/* */ private void readObject(ObjectInputStream stream)
/* */ throws IOException, ClassNotFoundException
/* */ {
/* 1035 */ stream.defaultReadObject();
/* */
/* */
/* 1038 */ this.astro = new CalendarAstronomer();
/* 1039 */ this.winterSolsticeCache = new CalendarCache();
/* 1040 */ this.newYearCache = new CalendarCache();
/* */ }
/* */ }
/* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\ibm\icu\util\ChineseCalendar.class
* Java compiler version: 5 (49.0)
* JD-Core Version: 0.7.1
*/