/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // BEGIN android-note // This implementation is based on an old version of Apache Harmony. The current // Harmony uses ICU4J, which makes it much simpler. We should consider updating // this implementation to leverage ICU4JNI. // END android-note package java.util; /** * {@code SimpleTimeZone} is a concrete subclass of {@code TimeZone} * that represents a time zone for use with a Gregorian calendar. This class * does not handle historical changes. * <p> * Use a negative value for {@code dayOfWeekInMonth} to indicate that * {@code SimpleTimeZone} should count from the end of the month * backwards. For example, Daylight Savings Time ends at the last * (dayOfWeekInMonth = -1) Sunday in October, at 2 AM in standard time. * * @see Calendar * @see GregorianCalendar * @see TimeZone */ class SimpleTimeZone extends TimeZone { // BEGIN android-removed // private static com.ibm.icu.util.TimeZone getICUTimeZone(final String name){ // return AccessController.doPrivileged(new PrivilegedAction<com.ibm.icu.util.TimeZone>(){ // public com.ibm.icu.util.TimeZone run() { // return com.ibm.icu.util.TimeZone.getTimeZone(name); // } // }); // } // END android-removed private int rawOffset; private int startYear, startMonth, startDay, startDayOfWeek, startTime; private int endMonth, endDay, endDayOfWeek, endTime; private int startMode, endMode; private static final int DOM_MODE = 1, DOW_IN_MONTH_MODE = 2, DOW_GE_DOM_MODE = 3, DOW_LE_DOM_MODE = 4; /** * The constant for representing a start or end time in GMT time mode. */ public static final int UTC_TIME = 2; /** * The constant for representing a start or end time in standard local time mode, * based on timezone's raw offset from GMT; does not include Daylight * savings. */ public static final int STANDARD_TIME = 1; /** * The constant for representing a start or end time in local wall clock time * mode, based on timezone's adjusted offset from GMT; includes * Daylight savings. */ public static final int WALL_TIME = 0; private boolean useDaylight; private int dstSavings = 3600000; private static final int MILLIS_PER_SECOND = 1000; private static final int MILLIS_PER_MINUTE = 60*MILLIS_PER_SECOND; private static final int MILLIS_PER_HOUR = 60*MILLIS_PER_MINUTE; // January 1, 1 CE Gregorian private static final int JULIAN_1_CE = 1721426; // January 1, 1970 CE Gregorian private static final int JULIAN_1970_CE = 2440588; private static final int[] MONTH_LENGTH = new int[] { 31,28,31,30,31,30,31,31,30,31,30,31, 31,29,31,30,31,30,31,31,30,31,30,31 }; private static final int[] DAYS_BEFORE = new int[] { 0,31,59,90,120,151,181,212,243,273,304,334, 0,31,60,91,121,152,182,213,244,274,305,335 }; /** * Return the number of days in the given month. * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc. * @param month 0-based month, with 0==Jan * @return the number of days in the given month */ private static final int monthLength(int year, int month) { return MONTH_LENGTH[month + (isLeapYear(year) ? 12 : 0)]; } // BEGIN android-removed // private final transient com.ibm.icu.util.TimeZone icuTZ; // // private final transient boolean isSimple; // END android-removed /** * Constructs a {@code SimpleTimeZone} with the given base time zone offset from GMT * and time zone ID. Timezone IDs can be obtained from * {@code TimeZone.getAvailableIDs}. Normally you should use {@code TimeZone.getDefault} to * construct a {@code TimeZone}. * * @param offset * the given base time zone offset to GMT. * @param name * the time zone ID which is obtained from * {@code TimeZone.getAvailableIDs}. */ public SimpleTimeZone(int offset, final String name) { setID(name); rawOffset = offset; // BEGIN android-removed // icuTZ = getICUTimeZone(name); // if (icuTZ instanceof com.ibm.icu.util.SimpleTimeZone) { // isSimple = true; // icuTZ.setRawOffset(offset); // } else { // isSimple = false; // } // useDaylight = icuTZ.useDaylightTime(); // END android-removed } /** * Constructs a {@code SimpleTimeZone} with the given base time zone offset from GMT, * time zone ID, and times to start and end the daylight savings time. Timezone IDs can * be obtained from {@code TimeZone.getAvailableIDs}. Normally you should use * {@code TimeZone.getDefault} to create a {@code TimeZone}. For a time zone that does not * use daylight saving time, do not use this constructor; instead you should * use {@code SimpleTimeZone(rawOffset, ID)}. * <p> * By default, this constructor specifies day-of-week-in-month rules. That * is, if the {@code startDay} is 1, and the {@code startDayOfWeek} is {@code SUNDAY}, then this * indicates the first Sunday in the {@code startMonth}. A {@code startDay} of -1 likewise * indicates the last Sunday. However, by using negative or zero values for * certain parameters, other types of rules can be specified. * <p> * Day of month: To specify an exact day of the month, such as March 1, set * {@code startDayOfWeek} to zero. * <p> * Day of week after day of month: To specify the first day of the week * occurring on or after an exact day of the month, make the day of the week * negative. For example, if {@code startDay} is 5 and {@code startDayOfWeek} is {@code -MONDAY}, * this indicates the first Monday on or after the 5th day of the * {@code startMonth}. * <p> * Day of week before day of month: To specify the last day of the week * occurring on or before an exact day of the month, make the day of the * week and the day of the month negative. For example, if {@code startDay} is {@code -21} * and {@code startDayOfWeek} is {@code -WEDNESDAY}, this indicates the last Wednesday on or * before the 21st of the {@code startMonth}. * <p> * The above examples refer to the {@code startMonth}, {@code startDay}, and {@code startDayOfWeek}; * the same applies for the {@code endMonth}, {@code endDay}, and {@code endDayOfWeek}. * <p> * The daylight savings time difference is set to the default value: one hour. * * @param offset * the given base time zone offset to GMT. * @param name * the time zone ID which is obtained from * {@code TimeZone.getAvailableIDs}. * @param startMonth * the daylight savings starting month. The month indexing is 0-based. eg, 0 * for January. * @param startDay * the daylight savings starting day-of-week-in-month. Please see * the member description for an example. * @param startDayOfWeek * the daylight savings starting day-of-week. Please see the * member description for an example. * @param startTime * the daylight savings starting time in local wall time, which * is standard time in this case. Please see the member * description for an example. * @param endMonth * the daylight savings ending month. The month indexing is 0-based. eg, 0 for * January. * @param endDay * the daylight savings ending day-of-week-in-month. Please see * the member description for an example. * @param endDayOfWeek * the daylight savings ending day-of-week. Please see the member * description for an example. * @param endTime * the daylight savings ending time in local wall time, which is * daylight time in this case. Please see the member description * for an example. * @throws IllegalArgumentException * if the month, day, dayOfWeek, or time parameters are out of * range for the start or end rule. */ public SimpleTimeZone(int offset, String name, int startMonth, int startDay, int startDayOfWeek, int startTime, int endMonth, int endDay, int endDayOfWeek, int endTime) { this(offset, name, startMonth, startDay, startDayOfWeek, startTime, endMonth, endDay, endDayOfWeek, endTime, 3600000); } /** * Constructs a {@code SimpleTimeZone} with the given base time zone offset from GMT, * time zone ID, times to start and end the daylight savings time, and * the daylight savings time difference in milliseconds. * * @param offset * the given base time zone offset to GMT. * @param name * the time zone ID which is obtained from * {@code TimeZone.getAvailableIDs}. * @param startMonth * the daylight savings starting month. Month is 0-based. eg, 0 * for January. * @param startDay * the daylight savings starting day-of-week-in-month. Please see * the description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param startDayOfWeek * the daylight savings starting day-of-week. Please see the * description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param startTime * The daylight savings starting time in local wall time, which * is standard time in this case. Please see the description of * {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param endMonth * the daylight savings ending month. Month is 0-based. eg, 0 for * January. * @param endDay * the daylight savings ending day-of-week-in-month. Please see * the description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param endDayOfWeek * the daylight savings ending day-of-week. Please see the description of * {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param endTime * the daylight savings ending time in local wall time, which is * daylight time in this case. Please see the description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} * for an example. * @param daylightSavings * the daylight savings time difference in milliseconds. * @throws IllegalArgumentException * if the month, day, dayOfWeek, or time parameters are out of * range for the start or end rule. */ public SimpleTimeZone(int offset, String name, int startMonth, int startDay, int startDayOfWeek, int startTime, int endMonth, int endDay, int endDayOfWeek, int endTime, int daylightSavings) { // BEGIN android-changed // icuTZ = getICUTimeZone(name); // if (icuTZ instanceof com.ibm.icu.util.SimpleTimeZone) { // isSimple = true; // com.ibm.icu.util.SimpleTimeZone tz = (com.ibm.icu.util.SimpleTimeZone)icuTZ; // tz.setRawOffset(offset); // tz.setStartRule(startMonth, startDay, startDayOfWeek, startTime); // tz.setEndRule(endMonth, endDay, endDayOfWeek, endTime); // tz.setDSTSavings(daylightSavings); // } else { // isSimple = false; // } // setID(name); // rawOffset = offset; this(offset, name); // END android-changed if (daylightSavings <= 0) { throw new IllegalArgumentException("Invalid daylightSavings: " + daylightSavings); } dstSavings = daylightSavings; setStartRule(startMonth, startDay, startDayOfWeek, startTime); setEndRule(endMonth, endDay, endDayOfWeek, endTime); // BEGIN android-removed // useDaylight = daylightSavings > 0 || icuTZ.useDaylightTime(); // END android-removed } /** * Construct a {@code SimpleTimeZone} with the given base time zone offset from GMT, * time zone ID, times to start and end the daylight savings time including a * mode specifier, the daylight savings time difference in milliseconds. * The mode specifies either {@link #WALL_TIME}, {@link #STANDARD_TIME}, or * {@link #UTC_TIME}. * * @param offset * the given base time zone offset to GMT. * @param name * the time zone ID which is obtained from * {@code TimeZone.getAvailableIDs}. * @param startMonth * the daylight savings starting month. The month indexing is 0-based. eg, 0 * for January. * @param startDay * the daylight savings starting day-of-week-in-month. Please see * the description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param startDayOfWeek * the daylight savings starting day-of-week. Please see the * description of {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param startTime * the time of day in milliseconds on which daylight savings * time starts, based on the {@code startTimeMode}. * @param startTimeMode * the mode (UTC, standard, or wall time) of the start time * value. * @param endDay * the day of the week on which daylight savings time ends. * @param endMonth * the daylight savings ending month. The month indexing is 0-based. eg, 0 for * January. * @param endDayOfWeek * the daylight savings ending day-of-week. Please see the description of * {@link #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)} for an example. * @param endTime * the time of day in milliseconds on which daylight savings * time ends, based on the {@code endTimeMode}. * @param endTimeMode * the mode (UTC, standard, or wall time) of the end time value. * @param daylightSavings * the daylight savings time difference in milliseconds. * @throws IllegalArgumentException * if the month, day, dayOfWeek, or time parameters are out of * range for the start or end rule. */ public SimpleTimeZone(int offset, String name, int startMonth, int startDay, int startDayOfWeek, int startTime, int startTimeMode, int endMonth, int endDay, int endDayOfWeek, int endTime, int endTimeMode, int daylightSavings) { this(offset, name, startMonth, startDay, startDayOfWeek, startTime, endMonth, endDay, endDayOfWeek, endTime, daylightSavings); startMode = startTimeMode; endMode = endTimeMode; } /** * Compares the specified object to this {@code SimpleTimeZone} and returns whether they * are equal. The object must be an instance of {@code SimpleTimeZone} and have the * same internal data. * * @param object * the object to compare with this object. * @return {@code true} if the specified object is equal to this * {@code SimpleTimeZone}, {@code false} otherwise. * @see #hashCode */ @Override public boolean equals(Object object) { if (!(object instanceof SimpleTimeZone)) { return false; } SimpleTimeZone tz = (SimpleTimeZone) object; return getID().equals(tz.getID()) && rawOffset == tz.rawOffset && useDaylight == tz.useDaylight && (!useDaylight || (startYear == tz.startYear && startMonth == tz.startMonth && startDay == tz.startDay && startMode == tz.startMode && startDayOfWeek == tz.startDayOfWeek && startTime == tz.startTime && endMonth == tz.endMonth && endDay == tz.endDay && endDayOfWeek == tz.endDayOfWeek && endTime == tz.endTime && endMode == tz.endMode && dstSavings == tz.dstSavings)); } @Override public int getDSTSavings() { if (!useDaylight) { return 0; } return dstSavings; } @Override public int getOffset(int era, int year, int month, int day, int dayOfWeek, int time) { if (era != GregorianCalendar.BC && era != GregorianCalendar.AD) { throw new IllegalArgumentException("Invalid era: " + era); } checkRange(month, dayOfWeek, time); if (month != Calendar.FEBRUARY || day != 29 || !isLeapYear(year)) { checkDay(month, day); } // BEGIN android-changed // return icuTZ.getOffset(era, year, month, day, dayOfWeek, time); if (!useDaylightTime() || era != GregorianCalendar.AD || year < startYear) { return rawOffset; } if (endMonth < startMonth) { if (month > endMonth && month < startMonth) { return rawOffset; } } else { if (month < startMonth || month > endMonth) { return rawOffset; } } int ruleDay = 0, daysInMonth, firstDayOfMonth = mod7(dayOfWeek - day); if (month == startMonth) { switch (startMode) { case DOM_MODE: ruleDay = startDay; break; case DOW_IN_MONTH_MODE: if (startDay >= 0) { ruleDay = mod7(startDayOfWeek - firstDayOfMonth) + 1 + (startDay - 1) * 7; } else { daysInMonth = GregorianCalendar.DaysInMonth[startMonth]; if (startMonth == Calendar.FEBRUARY && isLeapYear( year)) { daysInMonth += 1; } ruleDay = daysInMonth + 1 + mod7(startDayOfWeek - (firstDayOfMonth + daysInMonth)) + startDay * 7; } break; case DOW_GE_DOM_MODE: ruleDay = startDay + mod7(startDayOfWeek - (firstDayOfMonth + startDay - 1)); break; case DOW_LE_DOM_MODE: ruleDay = startDay + mod7(startDayOfWeek - (firstDayOfMonth + startDay - 1)); if (ruleDay != startDay) { ruleDay -= 7; } break; } if (ruleDay > day || ruleDay == day && time < startTime) { return rawOffset; } } int ruleTime = endTime - dstSavings; int nextMonth = (month + 1) % 12; if (month == endMonth || (ruleTime < 0 && nextMonth == endMonth)) { switch (endMode) { case DOM_MODE: ruleDay = endDay; break; case DOW_IN_MONTH_MODE: if (endDay >= 0) { ruleDay = mod7(endDayOfWeek - firstDayOfMonth) + 1 + (endDay - 1) * 7; } else { daysInMonth = GregorianCalendar.DaysInMonth[endMonth]; if (endMonth == Calendar.FEBRUARY && isLeapYear(year)) { daysInMonth++; } ruleDay = daysInMonth + 1 + mod7(endDayOfWeek - (firstDayOfMonth + daysInMonth)) + endDay * 7; } break; case DOW_GE_DOM_MODE: ruleDay = endDay + mod7( endDayOfWeek - (firstDayOfMonth + endDay - 1)); break; case DOW_LE_DOM_MODE: ruleDay = endDay + mod7( endDayOfWeek - (firstDayOfMonth + endDay - 1)); if (ruleDay != endDay) { ruleDay -= 7; } break; } int ruleMonth = endMonth; if (ruleTime < 0) { int changeDays = 1 - (ruleTime / 86400000); ruleTime = (ruleTime % 86400000) + 86400000; ruleDay -= changeDays; if (ruleDay <= 0) { if (--ruleMonth < Calendar.JANUARY) { ruleMonth = Calendar.DECEMBER; } ruleDay += GregorianCalendar.DaysInMonth[ruleMonth]; if (ruleMonth == Calendar.FEBRUARY && isLeapYear(year)) { ruleDay++; } } } if (month == ruleMonth) { if (ruleDay < day || ruleDay == day && time >= ruleTime) { return rawOffset; } } else if (nextMonth != ruleMonth) { return rawOffset; } } return rawOffset + dstSavings; // END android-changed } public int getOffset(long time) { // BEGIN android-changed: simplified variant of the ICU4J code. if (!useDaylightTime()) { return rawOffset; } int[] fields = timeToFields(time + rawOffset, null); return getOffset(GregorianCalendar.AD, fields[0], fields[1], fields[2], fields[3], fields[5]); // END android-changed } private static int[] timeToFields(long time, int[] fields) { if (fields == null || fields.length < 6) { fields = new int[6]; } long[] remainder = new long[1]; long day = floorDivide(time, 24*60*60*1000 /* milliseconds per day */, remainder); dayToFields(day, fields); fields[5] = (int)remainder[0]; return fields; } private static long floorDivide(long numerator, long denominator) { // We do this computation in order to handle // a numerator of Long.MIN_VALUE correctly return (numerator >= 0) ? numerator / denominator : ((numerator + 1) / denominator) - 1; } private static long floorDivide(long numerator, long denominator, long[] remainder) { if (numerator >= 0) { remainder[0] = numerator % denominator; return numerator / denominator; } long quotient = ((numerator + 1) / denominator) - 1; remainder[0] = numerator - (quotient * denominator); return quotient; } public static int[] dayToFields(long day, int[] fields) { if (fields == null || fields.length < 5) { fields = new int[5]; } // Convert from 1970 CE epoch to 1 CE epoch (Gregorian calendar) day += JULIAN_1970_CE - JULIAN_1_CE; long[] rem = new long[1]; long n400 = floorDivide(day, 146097, rem); long n100 = floorDivide(rem[0], 36524, rem); long n4 = floorDivide(rem[0], 1461, rem); long n1 = floorDivide(rem[0], 365, rem); int year = (int)(400 * n400 + 100 * n100 + 4 * n4 + n1); int dayOfYear = (int)rem[0]; if (n100 == 4 || n1 == 4) { dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle } else { ++year; } boolean isLeap = isLeapYear(year); int correction = 0; int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1 if (dayOfYear >= march1) { correction = isLeap ? 1 : 2; } int month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month int dayOfMonth = dayOfYear - DAYS_BEFORE[isLeap ? month + 12 : month] + 1; // one-based DOM int dayOfWeek = (int)((day + 2) % 7); // day 0 is Monday(2) if (dayOfWeek < 1 /* Sunday */) { dayOfWeek += 7; } dayOfYear++; // 1-based day of year fields[0] = year; fields[1] = month; fields[2] = dayOfMonth; fields[3] = dayOfWeek; fields[4] = dayOfYear; return fields; } @Override public int getRawOffset() { return rawOffset; } /** * Returns an integer hash code for the receiver. Objects which are equal * return the same value for this method. * * @return the receiver's hash. * @see #equals */ @Override public synchronized int hashCode() { int hashCode = getID().hashCode() + rawOffset; if (useDaylight) { hashCode += startYear + startMonth + startDay + startDayOfWeek + startTime + startMode + endMonth + endDay + endDayOfWeek + endTime + endMode + dstSavings; } return hashCode; } public boolean hasSameRules(TimeZone zone) { if (!(zone instanceof SimpleTimeZone)) { return false; } SimpleTimeZone tz = (SimpleTimeZone) zone; if (useDaylight != tz.useDaylight) { return false; } if (!useDaylight) { return rawOffset == tz.rawOffset; } return rawOffset == tz.rawOffset && dstSavings == tz.dstSavings && startYear == tz.startYear && startMonth == tz.startMonth && startDay == tz.startDay && startMode == tz.startMode && startDayOfWeek == tz.startDayOfWeek && startTime == tz.startTime && endMonth == tz.endMonth && endDay == tz.endDay && endDayOfWeek == tz.endDayOfWeek && endTime == tz.endTime && endMode == tz.endMode; } @Override public boolean inDaylightTime(Date time) { // BEGIN android-changed: reuse getOffset. return useDaylightTime() && getOffset(time.getTime()) != rawOffset; // END android-changed } private static boolean isLeapYear(int year) { if (year > 1582) { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } return year % 4 == 0; } // BEGIN android-added private int mod7(int num1) { int rem = num1 % 7; return (num1 < 0 && rem < 0) ? 7 + rem : rem; } // END android-added /** * Sets the daylight savings offset in milliseconds for this {@code SimpleTimeZone}. * * @param milliseconds * the daylight savings offset in milliseconds. */ public void setDSTSavings(int milliseconds) { if (milliseconds > 0) { dstSavings = milliseconds; } else { throw new IllegalArgumentException(); } } private void checkRange(int month, int dayOfWeek, int time) { if (month < Calendar.JANUARY || month > Calendar.DECEMBER) { throw new IllegalArgumentException("Invalid month: " + month); } if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) { throw new IllegalArgumentException("Invalid day of week: " + dayOfWeek); } if (time < 0 || time >= 24 * 3600000) { throw new IllegalArgumentException("Invalid time: " + time); } } private void checkDay(int month, int day) { if (day <= 0 || day > GregorianCalendar.DaysInMonth[month]) { throw new IllegalArgumentException("Invalid day of month: " + day); } } private void setEndMode() { if (endDayOfWeek == 0) { endMode = DOM_MODE; } else if (endDayOfWeek < 0) { endDayOfWeek = -endDayOfWeek; if (endDay < 0) { endDay = -endDay; endMode = DOW_LE_DOM_MODE; } else { endMode = DOW_GE_DOM_MODE; } } else { endMode = DOW_IN_MONTH_MODE; } useDaylight = startDay != 0 && endDay != 0; if (endDay != 0) { checkRange(endMonth, endMode == DOM_MODE ? 1 : endDayOfWeek, endTime); if (endMode != DOW_IN_MONTH_MODE) { checkDay(endMonth, endDay); } else { if (endDay < -5 || endDay > 5) { throw new IllegalArgumentException("Day of week in month: " + endDay); } } } if (endMode != DOM_MODE) { endDayOfWeek--; } } /** * Sets the rule which specifies the end of daylight savings time. * * @param month * the {@code Calendar} month in which daylight savings time ends. * @param dayOfMonth * the {@code Calendar} day of the month on which daylight savings time * ends. * @param time * the time of day in milliseconds standard time on which * daylight savings time ends. */ public void setEndRule(int month, int dayOfMonth, int time) { endMonth = month; endDay = dayOfMonth; endDayOfWeek = 0; // Initialize this value for hasSameRules() endTime = time; setEndMode(); // BEGIN android-removed // if (isSimple) { // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month, // dayOfMonth, time); // } // END android-removed } /** * Sets the rule which specifies the end of daylight savings time. * * @param month * the {@code Calendar} month in which daylight savings time ends. * @param day * the occurrence of the day of the week on which daylight * savings time ends. * @param dayOfWeek * the {@code Calendar} day of the week on which daylight savings time * ends. * @param time * the time of day in milliseconds standard time on which * daylight savings time ends. */ public void setEndRule(int month, int day, int dayOfWeek, int time) { endMonth = month; endDay = day; endDayOfWeek = dayOfWeek; endTime = time; setEndMode(); // BEGIN android-removed // if (isSimple) { // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month, day, // dayOfWeek, time); // } // END android-removed } /** * Sets the rule which specifies the end of daylight savings time. * * @param month * the {@code Calendar} month in which daylight savings time ends. * @param day * the {@code Calendar} day of the month. * @param dayOfWeek * the {@code Calendar} day of the week on which daylight savings time * ends. * @param time * the time of day in milliseconds on which daylight savings time * ends. * @param after * selects the day after or before the day of month. */ public void setEndRule(int month, int day, int dayOfWeek, int time, boolean after) { endMonth = month; endDay = after ? day : -day; endDayOfWeek = -dayOfWeek; endTime = time; setEndMode(); // BEGIN android-removed // if (isSimple) { // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month, day, // dayOfWeek, time, after); // } // END android-removed } /** * Sets the offset for standard time from GMT for this {@code SimpleTimeZone}. * * @param offset * the offset from GMT of standard time in milliseconds. */ public void setRawOffset(int offset) { rawOffset = offset; // BEGIN android-removed // icuTZ.setRawOffset(offset); // END android-removed } private void setStartMode() { if (startDayOfWeek == 0) { startMode = DOM_MODE; } else if (startDayOfWeek < 0) { startDayOfWeek = -startDayOfWeek; if (startDay < 0) { startDay = -startDay; startMode = DOW_LE_DOM_MODE; } else { startMode = DOW_GE_DOM_MODE; } } else { startMode = DOW_IN_MONTH_MODE; } useDaylight = startDay != 0 && endDay != 0; if (startDay != 0) { checkRange(startMonth, startMode == DOM_MODE ? 1 : startDayOfWeek, startTime); if (startMode != DOW_IN_MONTH_MODE) { checkDay(startMonth, startDay); } else { if (startDay < -5 || startDay > 5) { throw new IllegalArgumentException("Day of week in month: " + startDay); } } } if (startMode != DOM_MODE) { startDayOfWeek--; } } /** * Sets the rule which specifies the start of daylight savings time. * * @param month * the {@code Calendar} month in which daylight savings time starts. * @param dayOfMonth * the {@code Calendar} day of the month on which daylight savings time * starts. * @param time * the time of day in milliseconds on which daylight savings time * starts. */ public void setStartRule(int month, int dayOfMonth, int time) { startMonth = month; startDay = dayOfMonth; startDayOfWeek = 0; // Initialize this value for hasSameRules() startTime = time; setStartMode(); // BEGIN android-removed // if (isSimple) { // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(month, // dayOfMonth, time); // } // END android-removed } /** * Sets the rule which specifies the start of daylight savings time. * * @param month * the {@code Calendar} month in which daylight savings time starts. * @param day * the occurrence of the day of the week on which daylight * savings time starts. * @param dayOfWeek * the {@code Calendar} day of the week on which daylight savings time * starts. * @param time * the time of day in milliseconds on which daylight savings time * starts. */ public void setStartRule(int month, int day, int dayOfWeek, int time) { startMonth = month; startDay = day; startDayOfWeek = dayOfWeek; startTime = time; setStartMode(); // BEGIN android-removed // if (isSimple) { // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(month, day, // dayOfWeek, time); // } // END android-removed } /** * Sets the rule which specifies the start of daylight savings time. * * @param month * the {@code Calendar} month in which daylight savings time starts. * @param day * the {@code Calendar} day of the month. * @param dayOfWeek * the {@code Calendar} day of the week on which daylight savings time * starts. * @param time * the time of day in milliseconds on which daylight savings time * starts. * @param after * selects the day after or before the day of month. */ public void setStartRule(int month, int day, int dayOfWeek, int time, boolean after) { startMonth = month; startDay = after ? day : -day; startDayOfWeek = -dayOfWeek; startTime = time; setStartMode(); // BEGIN android-removed // if (isSimple) { // ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(month, day, // dayOfWeek, time, after); // } // END android-removed } /** * Sets the starting year for daylight savings time in this {@code SimpleTimeZone}. * Years before this start year will always be in standard time. * * @param year * the starting year. */ public void setStartYear(int year) { startYear = year; useDaylight = true; } /** * Returns the string representation of this {@code SimpleTimeZone}. * * @return the string representation of this {@code SimpleTimeZone}. */ @Override public String toString() { return getClass().getName() + "[id=" + getID() + ",offset=" + rawOffset + ",dstSavings=" + dstSavings + ",useDaylight=" + useDaylight + ",startYear=" + startYear + ",startMode=" + startMode + ",startMonth=" + startMonth + ",startDay=" + startDay + ",startDayOfWeek=" + (useDaylight && (startMode != DOM_MODE) ? startDayOfWeek + 1 : 0) + ",startTime=" + startTime + ",endMode=" + endMode + ",endMonth=" + endMonth + ",endDay=" + endDay + ",endDayOfWeek=" + (useDaylight && (endMode != DOM_MODE) ? endDayOfWeek + 1 : 0) + ",endTime=" + endTime + "]"; } @Override public boolean useDaylightTime() { return useDaylight; } }