📄 timezoneimpl.java
字号:
* values: * <dl> * <dt><code>DOM_MODE</code></dt> * <dd> * Exact day of week; e.g., March 1. * </dd> * <dt><code>DOW_IN_MONTH_MODE</code></dt> * <dd> * Day of week in month; e.g., last Sunday in March. * </dd> * <dt><code>DOW_GE_DOM_MODE</code></dt> * <dd> * Day of week after day of month; e.g., Sunday on or after March 15. * </dd> * <dt><code>DOW_LE_DOM_MODE</code></dt> * <dd> * Day of week before day of month; e.g., Sunday on or before March 15. * </dd> * </dl> * The setting of this field affects the interpretation of the * <code>endDay</code> field. * <p>If <code>useDaylight</code> is false, this value is ignored. * @serial * @since JDK1.1.4 */ private int endMode; /** * A positive value indicating the amount of time saved during DST in * milliseconds. * Typically one hour (3600000); sometimes 30 minutes (1800000). * <p>If <code>useDaylight</code> is false, this value is ignored. * @serial * @since JDK1.1.4 */ private int dstSavings; /** * Constants specifying values of startMode and endMode. */ private static final int DOM_MODE = 1; // Exact day of month, "Mar 1" private static final int DOW_IN_MONTH_MODE = 2; // Day of week in month, "lastSun" private static final int DOW_GE_DOM_MODE = 3; // Day of week after day of month, "Sun>=15" private static final int DOW_LE_DOM_MODE = 4; // Day of week before day of month, "Sun<=21" //---------------------------------------------------------------------- // Rule representation // // We represent the following flavors of rules: // 5 the fifth of the month // lastSun the last Sunday in the month // lastMon the last Monday in the month // Sun>=8 first Sunday on or after the eighth // Sun<=25 last Sunday on or before the 25th // This is further complicated by the fact that we need to remain // backward compatible with the 1.1 FCS. Finally, we need to minimize // API changes. In order to satisfy these requirements, we support // three representation systems, and we translate between them. // // INTERNAL REPRESENTATION // This is the format TimeZone objects take after construction or // streaming in is complete. Rules are represented directly, using an // unencoded format. We will discuss the start rule only below; the end // rule is analogous. // startMode Takes on enumerated values DAY_OF_MONTH, // DOW_IN_MONTH, DOW_AFTER_DOM, or DOW_BEFORE_DOM. // startDay The day of the month, or for DOW_IN_MONTH mode, a // value indicating which DOW, such as +1 for first, // +2 for second, -1 for last, etc. // startDayOfWeek The day of the week. Ignored for DAY_OF_MONTH. // // ENCODED REPRESENTATION // This is the format accepted by the constructor and by setStartRule() // and setEndRule(). It uses various combinations of positive, negative, // and zero values to encode the different rules. This representation // allows us to specify all the different rule flavors without altering // the API. // MODE startMonth startDay startDayOfWeek // DOW_IN_MONTH_MODE >=0 !=0 >0 // DOM_MODE >=0 >0 ==0 // DOW_GE_DOM_MODE >=0 >0 <0 // DOW_LE_DOM_MODE >=0 <0 <0 // (no DST) don't care ==0 don't care // // STREAMED REPRESENTATION // We must retain binary compatibility with the 1.1 FCS. The 1.1 code only // handles DOW_IN_MONTH_MODE and non-DST mode, the latter indicated by the // flag useDaylight. When we stream an object out, we translate into an // approximate DOW_IN_MONTH_MODE representation so the object can be parsed // and used by 1.1 code. Following that, we write out the full // representation separately so that contemporary code can recognize and // parse it. The full representation is written in a "packed" format, // consisting of a version number, a length, and an array of bytes. Future // versions of this class may specify different versions. If they wish to // include additional data, they should do so by storing them after the // packed representation below. //---------------------------------------------------------------------- /** * Given a set of encoded rules in startDay and startDayOfMonth, decode * them and set the startMode appropriately. Do the same for endDay and * endDayOfMonth. Upon entry, the day of week variables may be zero or * negative, in order to indicate special modes. The day of month * variables may also be negative. Upon exit, the mode variables will be * set, and the day of week and day of month variables will be positive. * This method also recognizes a startDay or endDay of zero as indicating * no DST. */ private void decodeRules() { decodeStartRule(); decodeEndRule(); } /** * Decode the start rule and validate the parameters. The parameters are * expected to be in encoded form, which represents the various rule modes * by negating or zeroing certain values. Representation formats are: * <p> * <pre> * DOW_IN_MONTH DOM DOW>=DOM DOW<=DOM no DST * ------------ ----- -------- -------- ---------- * month 0..11 same same same don't care * day -5..5 1..31 1..31 -1..-31 0 * dayOfWeek 1..7 0 -1..-7 -1..-7 don't care * time 0..ONEDAY same same same don't care * </pre> * The range for month does not include UNDECIMBER since this class is * really specific to Calendar, which does not use that month. * The range for time includes ONEDAY (vs. ending at ONEDAY-1) because the * end rule is an exclusive limit point. That is, the range of times that * are in DST include those >= the start and < the end. For this reason, * it should be possible to specify an end of ONEDAY in order to include the * entire day. Although this is equivalent to time 0 of the following day, * it's not always possible to specify that, for example, on December 31. * While arguably the start range should still be 0..ONEDAY-1, we keep * the start and end ranges the same for consistency. */ private void decodeStartRule() { useDaylight = (startDay != 0) && (endDay != 0); if (startDay != 0) { if (startMonth < Calendar.JANUARY || startMonth > Calendar.DECEMBER) { throw new IllegalArgumentException( "Illegal start month " + startMonth); } if (startTime < 0 || startTime > millisPerDay) { throw new IllegalArgumentException( "Illegal start time " + startTime); } if (startDayOfWeek == 0) { startMode = DOM_MODE; } else { if (startDayOfWeek > 0) { startMode = DOW_IN_MONTH_MODE; } else { startDayOfWeek = -startDayOfWeek; if (startDay > 0) { startMode = DOW_GE_DOM_MODE; } else { startDay = -startDay; startMode = DOW_LE_DOM_MODE; } } if (startDayOfWeek > Calendar.SATURDAY) { throw new IllegalArgumentException( "Illegal start day of week " + startDayOfWeek); } } if (startMode == DOW_IN_MONTH_MODE) { if (startDay < -5 || startDay > 5) { throw new IllegalArgumentException( "Illegal start day of week in month " + startDay); } } else if (startDay > staticMonthLength[startMonth]) { throw new IllegalArgumentException( "Illegal start day " + startDay); } } } /** * Decode the end rule and validate the parameters. This method is exactly * analogous to decodeStartRule(). * @see decodeStartRule */ private void decodeEndRule() { useDaylight = (startDay != 0) && (endDay != 0); if (endDay != 0) { if (endMonth < Calendar.JANUARY || endMonth > Calendar.DECEMBER) { throw new IllegalArgumentException( "Illegal end month " + endMonth); } if (endTime < 0 || endTime > millisPerDay) { throw new IllegalArgumentException( "Illegal end time " + endTime); } if (endDayOfWeek == 0) { endMode = DOM_MODE; } else { if (endDayOfWeek > 0) { endMode = DOW_IN_MONTH_MODE; } else { endDayOfWeek = -endDayOfWeek; if (endDay > 0) { endMode = DOW_GE_DOM_MODE; } else { endDay = -endDay; endMode = DOW_LE_DOM_MODE; } } if (endDayOfWeek > Calendar.SATURDAY) { throw new IllegalArgumentException( "Illegal end day of week " + endDayOfWeek); } } if (endMode == DOW_IN_MONTH_MODE) { if (endDay < -5 || endDay > 5) { throw new IllegalArgumentException( "Illegal end day of week in month " + endDay); } } else if (endDay > staticMonthLength[endMonth]) { throw new IllegalArgumentException( "Illegal end day " + endDay); } } } static TimeZone zones[] = { //---------------------------------------------------------- new TimeZoneImpl(0*ONE_HOUR, "GMT"), // GMT -(-) 0:00 - GMT new TimeZoneImpl(0*ONE_HOUR, "UTC"), /* NOTE: as in this example, most implementations will only include * a handful of timezones * look for the closing comment which has a string of '*' asterisks ************* //////////////////////////////////////////////////////////// // America //---------------------------------------------------------- new TimeZoneImpl(-10*ONE_HOUR, "America/Adak", Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, 1*ONE_HOUR), // Rule US 1967 max - Oct lastSun 2:00 0 S // Rule US 1987 max - Apr Sun>=1 2:00 1:00 D // America/Adak Alaska(US) -10:00 US HA%sT //---------------------------------------------------------- new TimeZoneImpl(-9*ONE_HOUR, "America/Anchorage", Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, 1*ONE_HOUR), // Rule US 1967 max - Oct lastSun 2:00 0 S // Rule US 1987 max - Apr Sun>=1 2:00 1:00 D // America/Anchorage Alaska(US) -9:00 US AK%sT new TimeZoneImpl(-9*ONE_HOUR, "AST", Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, 1*ONE_HOUR), //---------------------------------------------------------- new TimeZoneImpl(-8*ONE_HOUR, "America/Vancouver", Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, 1*ONE_HOUR), // Rule Vanc 1962 max - Oct lastSun 2:00 0 S // Rule Vanc 1987 max - Apr Sun>=1 2:00 1:00 D // America/Vancouver British Columbia(CA) -8:00 Vanc P%sT //---------------------------------------------------------- new TimeZoneImpl(-8*ONE_HOUR, "America/Tijuana", Calendar.APRIL, 1, -Calendar.SUNDAY, 2*ONE_HOUR, Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*ONE_HOUR, 1*ONE_HOUR), // Rule Mexico 1996 max - Apr Sun>=1 2:00 1:00 D
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -