📄 simpletimezone.java
字号:
// 7-argument getOffset(), and outside code should use Calendar.get(int // field) with fields ZONE_OFFSET and DST_OFFSET. We can't get rid of // this method because it's public API. - liu 8/10/98 if (month < Calendar.JANUARY || month > Calendar.DECEMBER) { throw new IllegalArgumentException("Illegal month " + month); } int monthLength, prevMonthLength; if ((era == GregorianCalendar.AD) && Gregorian.isLeapYear(year)) { monthLength = staticLeapMonthLength[month]; prevMonthLength = (month > 1) ? staticLeapMonthLength[month - 1] : 31; } else { monthLength = staticMonthLength[month]; prevMonthLength = (month > 1) ? staticMonthLength[month - 1] : 31; } if (true) { /* Use this parameter checking code for normal operation. Only one * of these two blocks should actually get compiled into the class * file. */ if ((era != GregorianCalendar.AD && era != GregorianCalendar.BC) || month < Calendar.JANUARY || month > Calendar.DECEMBER || day < 1 || day > monthLength || dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY || millis < 0 || millis >= millisPerDay) { throw new IllegalArgumentException(); } } else { /* This parameter checking code is better for debugging, but * overkill for normal operation. Only one of these two blocks * should actually get compiled into the class file. */ if (era != GregorianCalendar.AD && era != GregorianCalendar.BC) { throw new IllegalArgumentException("Illegal era " + era); } if (month < Calendar.JANUARY || month > Calendar.DECEMBER) { throw new IllegalArgumentException("Illegal month " + month); } if (day < 1 || day > monthLength) { throw new IllegalArgumentException("Illegal day " + day); } if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) { throw new IllegalArgumentException("Illegal day of week " + dayOfWeek); } if (millis < 0 || millis >= millisPerDay) { throw new IllegalArgumentException("Illegal millis " + millis); } } return getOffset(era, year, month, day, dayOfWeek, millis, monthLength, prevMonthLength); } /** * Gets offset, for current date, modified in case of * daylight saving time. This is the offset to add <em>to</em> UTC to get local time. * Gets the time zone offset, for current date, modified in case of daylight * saving time. This is the offset to add to UTC to get local time. Assume * that the start and end month are distinct. * @param era The era of the given date. * @param year The year in the given date. * @param month The month in the given date. Month is 0-based. e.g., * 0 for January. * @param day The day-in-month of the given date. * @param dayOfWeek The day-of-week of the given date. * @param millis The milliseconds in day in <em>standard</em> local time. * @param monthLength The length of the given month in days. * @param prevMonthLength The length of the previous month in days. * @return The offset to add to GMT to get local time. * @exception IllegalArgumentException the era, month, day, * dayOfWeek, millis, or monthLength parameters are out of range */ private int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis, int monthLength, int prevMonthLength) { int result = rawOffset; // Bail out if we are before the onset of daylight saving time if (!useDaylight || year < startYear || era != GregorianCalendar.AD) { return result; } // Check for southern hemisphere. We assume that the start and end // month are different. boolean southern = (startMonth > endMonth); // Compare the date to the starting and ending rules.+1 = date>rule, -1 // = date<rule, 0 = date==rule. int startCompare = compareToRule(month, monthLength, prevMonthLength, day, dayOfWeek, millis, startTimeMode == UTC_TIME ? -rawOffset : 0, startMode, startMonth, startDayOfWeek, startDay, startTime); int endCompare = 0; /* We don't always have to compute endCompare. For many instances, * startCompare is enough to determine if we are in DST or not. In the * northern hemisphere, if we are before the start rule, we can't have * DST. In the southern hemisphere, if we are after the start rule, we * must have DST. This is reflected in the way the next if statement * (not the one immediately following) short circuits. */ if (southern != (startCompare >= 0)) { /* For the ending rule comparison, we add the dstSavings to the millis * passed in to convert them from standard to wall time. We then must * normalize the millis to the range 0..millisPerDay-1. */ endCompare = compareToRule(month, monthLength, prevMonthLength, day, dayOfWeek, millis, endTimeMode == WALL_TIME ? dstSavings : (endTimeMode == UTC_TIME ? -rawOffset : 0), endMode, endMonth, endDayOfWeek, endDay, endTime); } // Check for both the northern and southern hemisphere cases. We // assume that in the northern hemisphere, the start rule is before the // end rule within the calendar year, and vice versa for the southern // hemisphere. if ((!southern && (startCompare >= 0 && endCompare < 0)) || (southern && (startCompare >= 0 || endCompare < 0))) { result += dstSavings; } return result; } /** * Compares the given date in the year to the given rule and returns 1, 0, * or -1, depending on whether the date is after, equal to, or before the * rule date. The millis are compared directly against the ruleMillis, so * any standard-daylight adjustments must be handled by the caller. * * @return 1 if the date is after the rule date, -1 if the date is before * the rule date, or 0 if the date is equal to the rule date. */ private static int compareToRule(int month, int monthLen, int prevMonthLen, int dayOfMonth, int dayOfWeek, int millis, int millisDelta, int ruleMode, int ruleMonth, int ruleDayOfWeek, int ruleDay, int ruleMillis) { // Make adjustments for startTimeMode and endTimeMode millis += millisDelta; while (millis >= millisPerDay) { millis -= millisPerDay; ++dayOfMonth; dayOfWeek = 1 + (dayOfWeek % 7); // dayOfWeek is one-based if (dayOfMonth > monthLen) { dayOfMonth = 1; /* When incrementing the month, it is desirable to overflow * from DECEMBER to DECEMBER+1, since we use the result to * compare against a real month. Wraparound of the value * leads to bug 4173604. */ ++month; } } while (millis < 0) { millis += millisPerDay; --dayOfMonth; dayOfWeek = 1 + ((dayOfWeek+5) % 7); // dayOfWeek is one-based if (dayOfMonth < 1) { dayOfMonth = prevMonthLen; --month; } } if (month < ruleMonth) { return -1; } if (month > ruleMonth) { return 1; } int ruleDayOfMonth = 0; switch (ruleMode) { case DOM_MODE: ruleDayOfMonth = ruleDay; break; case DOW_IN_MONTH_MODE: // In this case ruleDay is the day-of-week-in-month if (ruleDay > 0) { ruleDayOfMonth = 1 + (ruleDay - 1) * 7 + (7 + ruleDayOfWeek - (dayOfWeek - dayOfMonth + 1)) % 7; } else { // Assume ruleDay < 0 here ruleDayOfMonth = monthLen + (ruleDay + 1) * 7 - (7 + (dayOfWeek + monthLen - dayOfMonth) - ruleDayOfWeek) % 7; } break; case DOW_GE_DOM_MODE: ruleDayOfMonth = ruleDay + (49 + ruleDayOfWeek - ruleDay - dayOfWeek + dayOfMonth) % 7; break; case DOW_LE_DOM_MODE: ruleDayOfMonth = ruleDay - (49 - ruleDayOfWeek + ruleDay + dayOfWeek - dayOfMonth) % 7; // Note at this point ruleDayOfMonth may be <1, although it will // be >=1 for well-formed rules. break; } if (dayOfMonth < ruleDayOfMonth) { return -1; } if (dayOfMonth > ruleDayOfMonth) { return 1; } if (millis < ruleMillis) { return -1; } if (millis > ruleMillis) { return 1; } return 0; } /** * Gets the GMT offset for this time zone. * @return the GMT offset value in milliseconds * @see #setRawOffset */ public int getRawOffset() { // The given date will be taken into account while // we have the historical time zone data in place. return rawOffset; } /** * Sets the base time zone offset to GMT. * This is the offset to add to UTC to get local time. * @see #getRawOffset */ public void setRawOffset(int offsetMillis) { this.rawOffset = offsetMillis; } /** * Sets the amount of time in milliseconds that the clock is advanced * during daylight saving time. * @param millisSavedDuringDST the number of milliseconds the time is * advanced with respect to standard time when the daylight saving time rules * are in effect. A positive number, typically one hour (3600000). * @see #getDSTSavings * @since 1.2 */ public void setDSTSavings(int millisSavedDuringDST) { if (millisSavedDuringDST <= 0) { throw new IllegalArgumentException("Illegal daylight saving value: " + millisSavedDuringDST); } dstSavings = millisSavedDuringDST; } /** * Returns the amount of time in milliseconds that the clock is * advanced during daylight saving time. * * @return the number of milliseconds the time is advanced with * respect to standard time when the daylight saving rules are in * effect, or 0 (zero) if this time zone doesn't observe daylight * saving time. * * @see #setDSTSavings * @since 1.2 */ public int getDSTSavings() { if (useDaylight) { return dstSavings; } return 0; } /** * Queries if this time zone uses daylight saving time. * @return true if this time zone uses daylight saving time; * false otherwise. */ public boolean useDaylightTime() { return useDaylight; } /** * Queries if the given date is in daylight saving time. * @return true if daylight saving time is in effective at the * given date; false otherwise. */ public boolean inDaylightTime(Date date) { return (getOffset(date.getTime()) != rawOffset); } /** * Returns a clone of this <code>SimpleTimeZone</code> instance.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -