2 *******************************************************************************
\r
3 * Copyright (C) 2005-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.util;
\r
9 import java.util.Date;
\r
10 import java.util.Locale;
\r
13 * Base class for EthiopicCalendar and CopticCalendar.
\r
15 abstract class CECalendar extends Calendar {
\r
16 // jdk1.4.2 serialver
\r
17 private static final long serialVersionUID = -999547623066414271L;
\r
19 private static final int LIMITS[][] = {
\r
20 // Minimum Greatest Least Maximum
\r
22 { 0, 0, 1, 1 }, // ERA
\r
23 { 1, 1, 5000000, 5000000 }, // YEAR
\r
24 { 0, 0, 12, 12 }, // MONTH
\r
25 { 1, 1, 52, 53 }, // WEEK_OF_YEAR
\r
26 {/* */}, // WEEK_OF_MONTH
\r
27 { 1, 1, 5, 30 }, // DAY_OF_MONTH
\r
28 { 1, 1, 365, 366 }, // DAY_OF_YEAR
\r
29 {/* */}, // DAY_OF_WEEK
\r
30 { -1, -1, 1, 5 }, // DAY_OF_WEEK_IN_MONTH
\r
33 {/* */}, // HOUR_OF_DAY
\r
36 {/* */}, // MILLISECOND
\r
37 {/* */}, // ZONE_OFFSET
\r
38 {/* */}, // DST_OFFSET
\r
39 { -5000000, -5000000, 5000000, 5000000 }, // YEAR_WOY
\r
40 {/* */}, // DOW_LOCAL
\r
41 { -5000000, -5000000, 5000000, 5000000 }, // EXTENDED_YEAR
\r
42 {/* */}, // JULIAN_DAY
\r
43 {/* */}, // MILLISECONDS_IN_DAY
\r
46 //-------------------------------------------------------------------------
\r
48 //-------------------------------------------------------------------------
\r
51 * Constructs a default <code>CECalendar</code> using the current time
\r
52 * in the default time zone with the default locale.
\r
54 protected CECalendar() {
\r
55 this(TimeZone.getDefault(), ULocale.getDefault());
\r
59 * Constructs a <code>CECalendar</code> based on the current time
\r
60 * in the given time zone with the default locale.
\r
62 * @param zone The time zone for the new calendar.
\r
64 protected CECalendar(TimeZone zone) {
\r
65 this(zone, ULocale.getDefault());
\r
69 * Constructs a <code>CECalendar</code> based on the current time
\r
70 * in the default time zone with the given locale.
\r
72 * @param aLocale The locale for the new calendar.
\r
74 protected CECalendar(Locale aLocale) {
\r
75 this(TimeZone.getDefault(), aLocale);
\r
79 * Constructs a <code>CECalendar</code> based on the current time
\r
80 * in the default time zone with the given locale.
\r
82 * @param locale The locale for the new calendar.
\r
84 protected CECalendar(ULocale locale) {
\r
85 this(TimeZone.getDefault(), locale);
\r
89 * Constructs a <code>CECalendar</code> based on the current time
\r
90 * in the given time zone with the given locale.
\r
92 * @param zone The time zone for the new calendar.
\r
94 * @param aLocale The locale for the new calendar.
\r
96 protected CECalendar(TimeZone zone, Locale aLocale) {
\r
97 super(zone, aLocale);
\r
98 setTimeInMillis(System.currentTimeMillis());
\r
102 * Constructs a <code>CECalendar</code> based on the current time
\r
103 * in the given time zone with the given locale.
\r
105 * @param zone The time zone for the new calendar.
\r
107 * @param locale The locale for the new calendar.
\r
109 protected CECalendar(TimeZone zone, ULocale locale) {
\r
110 super(zone, locale);
\r
111 setTimeInMillis(System.currentTimeMillis());
\r
115 * Constructs a <code>CECalendar</code> with the given date set
\r
116 * in the default time zone with the default locale.
\r
118 * @param year The value used to set the calendar's {@link #YEAR YEAR} time field.
\r
120 * @param month The value used to set the calendar's {@link #MONTH MONTH} time field.
\r
121 * The value is 0-based. e.g., 0 for Tishri.
\r
123 * @param date The value used to set the calendar's {@link #DATE DATE} time field.
\r
125 protected CECalendar(int year, int month, int date) {
\r
126 super(TimeZone.getDefault(), ULocale.getDefault());
\r
127 this.set(year, month, date);
\r
131 * Constructs a <code>CECalendar</code> with the given date set
\r
132 * in the default time zone with the default locale.
\r
134 * @param date The date to which the new calendar is set.
\r
136 protected CECalendar(Date date) {
\r
137 super(TimeZone.getDefault(), ULocale.getDefault());
\r
138 this.setTime(date);
\r
142 * Constructs a <code>CECalendar</code> with the given date
\r
143 * and time set for the default time zone with the default locale.
\r
145 * @param year The value used to set the calendar's {@link #YEAR YEAR} time field.
\r
146 * @param month The value used to set the calendar's {@link #MONTH MONTH} time field.
\r
147 * The value is 0-based. e.g., 0 for Tishri.
\r
148 * @param date The value used to set the calendar's {@link #DATE DATE} time field.
\r
149 * @param hour The value used to set the calendar's {@link #HOUR_OF_DAY HOUR_OF_DAY} time field.
\r
150 * @param minute The value used to set the calendar's {@link #MINUTE MINUTE} time field.
\r
151 * @param second The value used to set the calendar's {@link #SECOND SECOND} time field.
\r
153 protected CECalendar(int year, int month, int date, int hour,
\r
154 int minute, int second)
\r
156 super(TimeZone.getDefault(), ULocale.getDefault());
\r
157 this.set(year, month, date, hour, minute, second);
\r
160 //-------------------------------------------------------------------------
\r
161 // Calendar framework
\r
162 //-------------------------------------------------------------------------
\r
165 * The Coptic and Ethiopic calendars differ only in their epochs.
\r
166 * This method must be implemented by CECalendar subclasses to
\r
167 * return the date offset from Julian.
\r
169 abstract protected int getJDEpochOffset();
\r
172 * Return JD of start of given month/extended year
\r
174 protected int handleComputeMonthStart(int eyear,
\r
176 boolean useMonth) {
\r
177 return ceToJD(eyear, emonth, 0, getJDEpochOffset());
\r
181 * Calculate the limit for a specified type of limit and field
\r
183 protected int handleGetLimit(int field, int limitType) {
\r
184 return LIMITS[field][limitType];
\r
187 // (The following method is not called because all existing subclasses
\r
191 * Return the number of days in the given month of the given extended
\r
192 * year of this calendar system. Subclasses should override this
\r
193 * method if they can provide a more correct or more efficient
\r
194 * implementation than the default implementation in Calendar.
\r
196 protected int handleGetMonthLength(int extendedYear, int month)
\r
199 // The Ethiopian and Coptic calendars have 13 months, 12 of 30 days each and
\r
200 // an intercalary month at the end of the year of 5 or 6 days, depending whether
\r
201 // the year is a leap year or not. The Leap Year follows the same rules as the
\r
202 // Julian Calendar so that the extra month always has six days in the year before
\r
203 // a Julian Leap Year.
\r
204 if ((month + 1) % 13 != 0)
\r
206 // not intercalary month
\r
211 // intercalary month 5 days + possible leap day
\r
212 return ((extendedYear % 4) / 3) + 5;
\r
218 //-------------------------------------------------------------------------
\r
219 // Calendar framework
\r
220 //-------------------------------------------------------------------------
\r
223 * Convert an Coptic/Ethiopic year, month and day to a Julian day
\r
224 * @param year the extended year
\r
225 * @param month the month
\r
226 * @param day the day
\r
227 * @return Julian day
\r
229 public static int ceToJD(long year, int month, int day, int jdEpochOffset) {
\r
231 // Julian<->Ethiopic algorithms from:
\r
232 // "Calendars in Ethiopia", Berhanu Beyene, Manfred Kudlek, International Conference
\r
233 // of Ethiopian Studies XV, Hamburg, 2003
\r
235 // handle month > 12, < 0 (e.g. from add/set)
\r
236 if ( month >= 0 ) {
\r
241 year += month/13 - 1;
\r
242 month = month%13 + 12;
\r
245 jdEpochOffset // difference from Julian epoch to 1,1,1
\r
246 + 365 * year // number of days from years
\r
247 + floorDivide(year, 4) // extra day of leap year
\r
248 + 30 * month // number of days from months (months are 0-based)
\r
249 + day - 1 // number of days for present month (1 based)
\r
254 * Convert a Julian day to an Coptic/Ethiopic year, month and day
\r
256 public static void jdToCE(int julianDay, int jdEpochOffset, int[] fields) {
\r
257 int c4; // number of 4 year cycle (1461 days)
\r
258 int[] r4 = new int[1]; // remainder of 4 year cycle, always positive
\r
260 c4 = floorDivide(julianDay - jdEpochOffset, 1461, r4);
\r
263 fields[0] = 4 * c4 + (r4[0]/365 - r4[0]/1460); // 4 * <number of 4year cycle> + <years within the last cycle>
\r
265 int doy = (r4[0] == 1460) ? 365 : (r4[0] % 365); // days in present year
\r
268 fields[1] = doy / 30; // 30 -> Coptic/Ethiopic month length up to 12th month
\r
270 fields[2] = (doy % 30) + 1; // 1-based days in a month
\r