📄 simpletimezone.java
字号:
/** * This constructs a new SimpleTimeZone that supports a daylight savings * rule. The parameter are the same as for the constructor above, except * there are the additional startTimeMode, endTimeMode, and dstSavings * parameters. * * @param startTimeMode the mode that start times are specified in. One of * WALL_TIME, STANDARD_TIME, or UTC_TIME. * @param endTimeMode the mode that end times are specified in. One of * WALL_TIME, STANDARD_TIME, or UTC_TIME. * @param dstSavings the amount of savings for daylight savings * time in milliseconds. This must be positive. * @throws IllegalArgumentException if parameters are invalid or out of * range. * @since 1.4 */ public SimpleTimeZone(int rawOffset, String id, int startMonth, int startDayOfWeekInMonth, int startDayOfWeek, int startTime, int startTimeMode, int endMonth, int endDayOfWeekInMonth, int endDayOfWeek, int endTime, int endTimeMode, int dstSavings) { this.rawOffset = rawOffset; setID(id); useDaylight = true; if (startTimeMode < WALL_TIME || startTimeMode > UTC_TIME) throw new IllegalArgumentException("startTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME"); if (endTimeMode < WALL_TIME || endTimeMode > UTC_TIME) throw new IllegalArgumentException("endTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME"); this.startTimeMode = startTimeMode; this.endTimeMode = endTimeMode; setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime); setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); if (startMonth == endMonth) throw new IllegalArgumentException("startMonth and endMonth must be different"); this.startYear = 0; this.dstSavings = dstSavings; } /** * Sets the first year, where daylight savings applies. The daylight * savings rule never apply for years in the BC era. Note that this * is gregorian calendar specific. * @param year the start year. */ public void setStartYear(int year) { startYear = year; useDaylight = true; } /** * Checks if the month, day, dayOfWeek arguments are in range and * returns the mode of the rule. * @param month the month parameter as in the constructor * @param day the day parameter as in the constructor * @param dayOfWeek the day of week parameter as in the constructor * @return the mode of this rule see startMode. * @exception IllegalArgumentException if parameters are out of range. * @see #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int) * @see #startMode */ private int checkRule(int month, int day, int dayOfWeek) { if (month < 0 || month > 11) throw new IllegalArgumentException("month out of range"); int daysInMonth = getDaysInMonth(month, 1); if (dayOfWeek == 0) { if (day <= 0 || day > daysInMonth) throw new IllegalArgumentException("day out of range"); return DOM_MODE; } else if (dayOfWeek > 0) { if (Math.abs(day) > (daysInMonth + 6) / 7) throw new IllegalArgumentException("dayOfWeekInMonth out of range"); if (dayOfWeek > Calendar.SATURDAY) throw new IllegalArgumentException("dayOfWeek out of range"); return DOW_IN_MONTH_MODE; } else { if (day == 0 || Math.abs(day) > daysInMonth) throw new IllegalArgumentException("day out of range"); if (dayOfWeek < -Calendar.SATURDAY) throw new IllegalArgumentException("dayOfWeek out of range"); if (day < 0) return DOW_LE_DOM_MODE; else return DOW_GE_DOM_MODE; } } /** * Sets the daylight savings start rule. You must also set the * end rule with <code>setEndRule</code> or the result of * getOffset is undefined. For the parameters see the ten-argument * constructor above. * * @param month The month where daylight savings start, zero * based. You should use the constants in Calendar. * @param day A day of month or day of week in month. * @param dayOfWeek The day of week where daylight savings start. * @param time The time in milliseconds standard time where daylight * savings start. * @exception IllegalArgumentException if parameters are out of range. * @see SimpleTimeZone */ public void setStartRule(int month, int day, int dayOfWeek, int time) { this.startMode = checkRule(month, day, dayOfWeek); this.startMonth = month; this.startDay = day; this.startDayOfWeek = Math.abs(dayOfWeek); if (this.startTimeMode == WALL_TIME || this.startTimeMode == STANDARD_TIME) this.startTime = time; else // Convert from UTC to STANDARD this.startTime = time + this.rawOffset; useDaylight = true; } /** * Sets the daylight savings start rule. You must also set the * end rule with <code>setEndRule</code> or the result of * getOffset is undefined. For the parameters see the ten-argument * constructor above. * * Note that this API isn't incredibly well specified. It appears that the * after flag must override the parameters, since normally, the day and * dayofweek can select this. I.e., if day < 0 and dayOfWeek < 0, on or * before mode is chosen. But if after == true, this implementation * overrides the signs of the other arguments. And if dayOfWeek == 0, it * falls back to the behavior in the other APIs. I guess this should be * checked against Sun's implementation. * * @param month The month where daylight savings start, zero * based. You should use the constants in Calendar. * @param day A day of month or day of week in month. * @param dayOfWeek The day of week where daylight savings start. * @param time The time in milliseconds standard time where daylight * savings start. * @param after If true, day and dayOfWeek specify first day of week on or * after day, else first day of week on or before. * @since 1.2 * @see SimpleTimeZone */ public void setStartRule(int month, int day, int dayOfWeek, int time, boolean after) { // FIXME: XXX: Validate that checkRule and offset processing work with on // or before mode. this.startDay = after ? Math.abs(day) : -Math.abs(day); this.startDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek); this.startMode = (dayOfWeek != 0) ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE) : checkRule(month, day, dayOfWeek); this.startDay = Math.abs(this.startDay); this.startDayOfWeek = Math.abs(this.startDayOfWeek); this.startMonth = month; if (this.startTimeMode == WALL_TIME || this.startTimeMode == STANDARD_TIME) this.startTime = time; else // Convert from UTC to STANDARD this.startTime = time + this.rawOffset; useDaylight = true; } /** * Sets the daylight savings start rule. You must also set the * end rule with <code>setEndRule</code> or the result of * getOffset is undefined. For the parameters see the ten-argument * constructor above. * * @param month The month where daylight savings start, zero * based. You should use the constants in Calendar. * @param day A day of month or day of week in month. * @param time The time in milliseconds standard time where daylight * savings start. * @see SimpleTimeZone * @since 1.2 */ public void setStartRule(int month, int day, int time) { setStartRule(month, day, 0, time); } /** * Sets the daylight savings end rule. You must also set the * start rule with <code>setStartRule</code> or the result of * getOffset is undefined. For the parameters see the ten-argument * constructor above. * * @param month The end month of daylight savings. * @param day A day in month, or a day of week in month. * @param dayOfWeek A day of week, when daylight savings ends. * @param time A time in millis in standard time. * @see #setStartRule(int, int, int, int) */ public void setEndRule(int month, int day, int dayOfWeek, int time) { this.endMode = checkRule(month, day, dayOfWeek); this.endMonth = month; this.endDay = day; this.endDayOfWeek = Math.abs(dayOfWeek); if (this.endTimeMode == WALL_TIME) this.endTime = time; else if (this.endTimeMode == STANDARD_TIME) // Convert from STANDARD to DST this.endTime = time + this.dstSavings; else // Convert from UTC to DST this.endTime = time + this.rawOffset + this.dstSavings; useDaylight = true; } /** * Sets the daylight savings end rule. You must also set the * start rule with <code>setStartRule</code> or the result of * getOffset is undefined. For the parameters see the ten-argument * constructor above. * * Note that this API isn't incredibly well specified. It appears that the * after flag must override the parameters, since normally, the day and * dayofweek can select this. I.e., if day < 0 and dayOfWeek < 0, on or * before mode is chosen. But if after == true, this implementation * overrides the signs of the other arguments. And if dayOfWeek == 0, it * falls back to the behavior in the other APIs. I guess this should be * checked against Sun's implementation. * * @param month The end month of daylight savings. * @param day A day in month, or a day of week in month. * @param dayOfWeek A day of week, when daylight savings ends. * @param time A time in millis in standard time. * @param after If true, day and dayOfWeek specify first day of week on or * after day, else first day of week on or before. * @since 1.2 * @see #setStartRule(int, int, int, int, boolean) */ public void setEndRule(int month, int day, int dayOfWeek, int time, boolean after) { // FIXME: XXX: Validate that checkRule and offset processing work with on // or before mode. this.endDay = after ? Math.abs(day) : -Math.abs(day); this.endDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek); this.endMode = (dayOfWeek != 0) ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE) : checkRule(month, day, dayOfWeek); this.endDay = Math.abs(this.endDay); this.endDayOfWeek = Math.abs(endDayOfWeek); this.endMonth = month; if (this.endTimeMode == WALL_TIME) this.endTime = time; else if (this.endTimeMode == STANDARD_TIME) // Convert from STANDARD to DST this.endTime = time + this.dstSavings; else // Convert from UTC to DST this.endTime = time + this.rawOffset + this.dstSavings; useDaylight = true; } /** * Sets the daylight savings end rule. You must also set the * start rule with <code>setStartRule</code> or the result of * getOffset is undefined. For the parameters see the ten-argument * constructor above. * * @param month The end month of daylight savings. * @param day A day in month, or a day of week in month. * @param time A time in millis in standard time. * @see #setStartRule(int, int, int) */ public void setEndRule(int month, int day, int time) { setEndRule(month, day, 0, time); } /** * Gets the time zone offset, for current date, modified in case of * daylight savings. This is the offset to add to UTC to get the local * time. * * In the standard JDK the results given by this method may result in * inaccurate results at the end of February or the beginning of March. * To avoid this, you should use Calendar instead: * <code>offset = cal.get(Calendar.ZONE_OFFSET) * + cal.get(Calendar.DST_OFFSET);</code> * * This version doesn't suffer this inaccuracy. * * The arguments don't follow the approach for setting start and end rules. * The day must be a positive number and dayOfWeek must be a positive value * from Calendar. dayOfWeek is redundant, but must match the other values * or an inaccurate result may be returned. * * @param era the era of the given date * @param year the year of the given date * @param month the month of the given date, 0 for January. * @param day the day of month * @param dayOfWeek the day of week; this must match the other fields. * @param millis the millis in the day (in local standard time) * @return the time zone offset in milliseconds. * @throws IllegalArgumentException if arguments are incorrect. */ public int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis) { int daysInMonth = getDaysInMonth(month, year); if (day < 1 || day > daysInMonth) throw new IllegalArgumentException("day out of range"); if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) throw new IllegalArgumentException("dayOfWeek out of range"); if (month < Calendar.JANUARY || month > Calendar.DECEMBER) throw new IllegalArgumentException("month out of range:" + month); // This method is called by Calendar, so we mustn't use that class. int daylightSavings = 0; if (useDaylight && era == GregorianCalendar.AD && year >= startYear) { // This does only work for Gregorian calendars :-( // This is mainly because setStartYear doesn't take an era. boolean afterStart = ! isBefore(year, month, day, dayOfWeek, millis, startMode, startMonth, startDay, startDayOfWeek, startTime); boolean beforeEnd = isBefore(year, month, day, dayOfWeek, millis + dstSavings, endMode, endMonth, endDay, endDayOfWeek, endTime); if (startMonth < endMonth) // use daylight savings, if the date is after the start of // savings, and before the end of savings. daylightSavings = afterStart && beforeEnd ? dstSavings : 0; else // use daylight savings, if the date is before the end of // savings, or after the start of savings. daylightSavings = beforeEnd || afterStart ? dstSavings : 0; } return rawOffset + daylightSavings; } /** * Returns the time zone offset to GMT in milliseconds, ignoring * day light savings. * @return the time zone offset. */ public int getRawOffset() { return rawOffset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -