38 |
|
|
39 |
package java.util; |
package java.util; |
40 |
|
|
41 |
|
|
42 |
/** |
/** |
43 |
* This class represents a simple time zone offset and handles |
* This class represents a simple time zone offset and handles |
44 |
* daylight savings. It can only handle one daylight savings rule, so |
* daylight savings. It can only handle one daylight savings rule, so |
50 |
* lying in the AD era. |
* lying in the AD era. |
51 |
* |
* |
52 |
* @see Calendar |
* @see Calendar |
53 |
* @see GregorianCalender |
* @see GregorianCalender |
54 |
* @author Jochen Hoenicke |
* @author Jochen Hoenicke |
55 |
*/ |
*/ |
56 |
public class SimpleTimeZone extends TimeZone |
public class SimpleTimeZone extends TimeZone |
57 |
{ |
{ |
58 |
/** |
/** |
59 |
* The raw time zone offset in milliseconds to GMT, ignoring |
* The raw time zone offset in milliseconds to GMT, ignoring |
60 |
* daylight savings. |
* daylight savings. |
61 |
* @serial |
* @serial |
62 |
*/ |
*/ |
63 |
private int rawOffset; |
private int rawOffset; |
78 |
private int dstSavings = 60 * 60 * 1000; |
private int dstSavings = 60 * 60 * 1000; |
79 |
|
|
80 |
/** |
/** |
81 |
* The first year, in which daylight savings rules applies. |
* The first year, in which daylight savings rules applies. |
82 |
* @serial |
* @serial |
83 |
*/ |
*/ |
84 |
private int startYear; |
private int startYear; |
|
|
|
85 |
private static final int DOM_MODE = 1; |
private static final int DOM_MODE = 1; |
86 |
private static final int DOW_IN_MONTH_MODE = 2; |
private static final int DOW_IN_MONTH_MODE = 2; |
87 |
private static final int DOW_GE_DOM_MODE = 3; |
private static final int DOW_GE_DOM_MODE = 3; |
88 |
private static final int DOW_LE_DOM_MODE = 4; |
private static final int DOW_LE_DOM_MODE = 4; |
89 |
|
|
90 |
/** |
/** |
91 |
* The mode of the start rule. This takes one of the following values: |
* The mode of the start rule. This takes one of the following values: |
92 |
* <dl> |
* <dl> |
119 |
|
|
120 |
/** |
/** |
121 |
* The month in which daylight savings start. This is one of the |
* The month in which daylight savings start. This is one of the |
122 |
* constants Calendar.JANUARY, ..., Calendar.DECEMBER. |
* constants Calendar.JANUARY, ..., Calendar.DECEMBER. |
123 |
* @serial |
* @serial |
124 |
*/ |
*/ |
125 |
private int startMonth; |
private int startMonth; |
128 |
* This variable can have different meanings. See startMode for details |
* This variable can have different meanings. See startMode for details |
129 |
* @see #startMode; |
* @see #startMode; |
130 |
* @serial |
* @serial |
131 |
*/ |
*/ |
132 |
private int startDay; |
private int startDay; |
133 |
|
|
134 |
/** |
/** |
135 |
* This variable specifies the day of week the change takes place. If |
* This variable specifies the day of week the change takes place. If |
136 |
* startMode == DOM_MODE, this is undefined. |
* startMode == DOM_MODE, this is undefined. |
137 |
* @serial |
* @serial |
138 |
* @see #startMode; |
* @see #startMode; |
139 |
*/ |
*/ |
140 |
private int startDayOfWeek; |
private int startDayOfWeek; |
141 |
|
|
142 |
/** |
/** |
143 |
* This variable specifies the time of change to daylight savings. |
* This variable specifies the time of change to daylight savings. |
144 |
* This time is given in milliseconds after midnight local |
* This time is given in milliseconds after midnight local |
145 |
* standard time. |
* standard time. |
146 |
* @serial |
* @serial |
147 |
*/ |
*/ |
148 |
private int startTime; |
private int startTime; |
157 |
|
|
158 |
/** |
/** |
159 |
* The month in which daylight savings ends. This is one of the |
* The month in which daylight savings ends. This is one of the |
160 |
* constants Calendar.JANUARY, ..., Calendar.DECEMBER. |
* constants Calendar.JANUARY, ..., Calendar.DECEMBER. |
161 |
* @serial |
* @serial |
162 |
*/ |
*/ |
163 |
private int endMonth; |
private int endMonth; |
164 |
|
|
165 |
/** |
/** |
167 |
* It can take the same values as startMode. |
* It can take the same values as startMode. |
168 |
* @serial |
* @serial |
169 |
* @see #startMode |
* @see #startMode |
170 |
*/ |
*/ |
171 |
private int endMode; |
private int endMode; |
172 |
|
|
173 |
/** |
/** |
176 |
* @see #startMode; |
* @see #startMode; |
177 |
*/ |
*/ |
178 |
private int endDay; |
private int endDay; |
179 |
|
|
180 |
/** |
/** |
181 |
* This variable specifies the day of week the change takes place. If |
* This variable specifies the day of week the change takes place. If |
182 |
* endMode == DOM_MODE, this is undefined. |
* endMode == DOM_MODE, this is undefined. |
183 |
* @serial |
* @serial |
184 |
* @see #startMode; |
* @see #startMode; |
185 |
*/ |
*/ |
186 |
private int endDayOfWeek; |
private int endDayOfWeek; |
187 |
|
|
188 |
/** |
/** |
189 |
* This variable specifies the time of change back to standard time. |
* This variable specifies the time of change back to standard time. |
190 |
* This time is given in milliseconds after midnight local |
* This time is given in milliseconds after midnight local |
191 |
* standard time. |
* standard time. |
192 |
* @serial |
* @serial |
193 |
*/ |
*/ |
194 |
private int endTime; |
private int endTime; |
210 |
* @serial |
* @serial |
211 |
*/ |
*/ |
212 |
private byte[] monthLength = monthArr; |
private byte[] monthLength = monthArr; |
213 |
private static final byte[] monthArr = |
private static final byte[] monthArr = |
214 |
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
{ |
215 |
|
31, 28, 31, 30, 31, 30, 31, 31, 30, |
216 |
|
31, 30, 31 |
217 |
|
}; |
218 |
|
|
219 |
/** |
/** |
220 |
* The version of the serialized data on the stream. |
* The version of the serialized data on the stream. |
235 |
* When streaming out this class it is always written in the latest |
* When streaming out this class it is always written in the latest |
236 |
* version. |
* version. |
237 |
* @serial |
* @serial |
238 |
* @since JDK1.1.4 |
* @since JDK1.1.4 |
239 |
*/ |
*/ |
240 |
private int serialVersionOnStream = 2; |
private int serialVersionOnStream = 2; |
|
|
|
241 |
private static final long serialVersionUID = -403250971215465050L; |
private static final long serialVersionUID = -403250971215465050L; |
242 |
|
|
243 |
/** |
/** |
259 |
|
|
260 |
/** |
/** |
261 |
* Create a <code>SimpleTimeZone</code> with the given time offset |
* Create a <code>SimpleTimeZone</code> with the given time offset |
262 |
* from GMT and without daylight savings. |
* from GMT and without daylight savings. |
263 |
* @param rawOffset the time offset from GMT in milliseconds. |
* @param rawOffset the time offset from GMT in milliseconds. |
264 |
* @param id The identifier of this time zone. |
* @param id The identifier of this time zone. |
265 |
*/ |
*/ |
266 |
public SimpleTimeZone(int rawOffset, String id) |
public SimpleTimeZone(int rawOffset, String id) |
267 |
{ |
{ |
275 |
* Create a <code>SimpleTimeZone</code> with the given time offset |
* Create a <code>SimpleTimeZone</code> with the given time offset |
276 |
* from GMT and with daylight savings. The start/end parameters |
* from GMT and with daylight savings. The start/end parameters |
277 |
* can have different meaning (replace WEEKDAY with a real day of |
* can have different meaning (replace WEEKDAY with a real day of |
278 |
* week). Only the first two meanings were supported by earlier |
* week). Only the first two meanings were supported by earlier |
279 |
* versions of jdk. |
* versions of jdk. |
280 |
* |
* |
281 |
* <dl> |
* <dl> |
298 |
* must make sure that this day lies in the same month. </dd> |
* must make sure that this day lies in the same month. </dd> |
299 |
* </dl> |
* </dl> |
300 |
* |
* |
301 |
* If you give a non existing month, a day that is zero, or too big, |
* If you give a non existing month, a day that is zero, or too big, |
302 |
* or a dayOfWeek that is too big, the result is undefined. |
* or a dayOfWeek that is too big, the result is undefined. |
303 |
* |
* |
304 |
* The start rule must have a different month than the end rule. |
* The start rule must have a different month than the end rule. |
305 |
* This restriction shouldn't hurt for all possible time zones. |
* This restriction shouldn't hurt for all possible time zones. |
306 |
* |
* |
307 |
* @param rawOffset The time offset from GMT in milliseconds. |
* @param rawOffset The time offset from GMT in milliseconds. |
308 |
* @param id The identifier of this time zone. |
* @param id The identifier of this time zone. |
309 |
* @param startMonth The start month of daylight savings; use the |
* @param startMonth The start month of daylight savings; use the |
314 |
* @param startTime A time in millis in standard time. |
* @param startTime A time in millis in standard time. |
315 |
* @param endMonth The end month of daylight savings; use the |
* @param endMonth The end month of daylight savings; use the |
316 |
* constants in Calendar. |
* constants in Calendar. |
317 |
* @param endday A day in month or a day of week number, as |
* @param endday A day in month or a day of week number, as |
318 |
* described above. |
* described above. |
319 |
* @param endDayOfWeek The end rule day of week; see above. |
* @param endDayOfWeek The end rule day of week; see above. |
320 |
* @param endTime A time in millis in standard time. |
* @param endTime A time in millis in standard time. |
321 |
* @throws IllegalArgumentException if parameters are invalid or out of |
* @throws IllegalArgumentException if parameters are invalid or out of |
322 |
* range. |
* range. |
323 |
*/ |
*/ |
324 |
public SimpleTimeZone(int rawOffset, String id, |
public SimpleTimeZone(int rawOffset, String id, int startMonth, |
325 |
int startMonth, int startDayOfWeekInMonth, |
int startDayOfWeekInMonth, int startDayOfWeek, |
326 |
int startDayOfWeek, int startTime, |
int startTime, int endMonth, int endDayOfWeekInMonth, |
327 |
int endMonth, int endDayOfWeekInMonth, |
int endDayOfWeek, int endTime) |
|
int endDayOfWeek, int endTime) |
|
328 |
{ |
{ |
329 |
this.rawOffset = rawOffset; |
this.rawOffset = rawOffset; |
330 |
setID(id); |
setID(id); |
331 |
useDaylight = true; |
useDaylight = true; |
332 |
|
|
333 |
setStartRule(startMonth, startDayOfWeekInMonth, |
setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime); |
|
startDayOfWeek, startTime); |
|
334 |
setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); |
setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); |
335 |
if (startMonth == endMonth) |
if (startMonth == endMonth) |
336 |
throw new IllegalArgumentException |
throw new IllegalArgumentException("startMonth and endMonth must be different"); |
|
("startMonth and endMonth must be different"); |
|
337 |
this.startYear = 0; |
this.startYear = 0; |
338 |
} |
} |
339 |
|
|
346 |
* time in milliseconds. This must be positive. |
* time in milliseconds. This must be positive. |
347 |
* @since 1.2 |
* @since 1.2 |
348 |
*/ |
*/ |
349 |
public SimpleTimeZone(int rawOffset, String id, |
public SimpleTimeZone(int rawOffset, String id, int startMonth, |
350 |
int startMonth, int startDayOfWeekInMonth, |
int startDayOfWeekInMonth, int startDayOfWeek, |
351 |
int startDayOfWeek, int startTime, |
int startTime, int endMonth, int endDayOfWeekInMonth, |
352 |
int endMonth, int endDayOfWeekInMonth, |
int endDayOfWeek, int endTime, int dstSavings) |
353 |
int endDayOfWeek, int endTime, int dstSavings) |
{ |
354 |
{ |
this(rawOffset, id, startMonth, startDayOfWeekInMonth, startDayOfWeek, |
355 |
this(rawOffset, id, |
startTime, endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); |
|
startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime, |
|
|
endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); |
|
356 |
|
|
357 |
this.dstSavings = dstSavings; |
this.dstSavings = dstSavings; |
358 |
} |
} |
373 |
* range. |
* range. |
374 |
* @since 1.4 |
* @since 1.4 |
375 |
*/ |
*/ |
376 |
public SimpleTimeZone(int rawOffset, String id, |
public SimpleTimeZone(int rawOffset, String id, int startMonth, |
377 |
int startMonth, int startDayOfWeekInMonth, |
int startDayOfWeekInMonth, int startDayOfWeek, |
378 |
int startDayOfWeek, int startTime, int startTimeMode, |
int startTime, int startTimeMode, int endMonth, |
379 |
int endMonth, int endDayOfWeekInMonth, |
int endDayOfWeekInMonth, int endDayOfWeek, |
380 |
int endDayOfWeek, int endTime, int endTimeMode, |
int endTime, int endTimeMode, int dstSavings) |
|
int dstSavings) |
|
381 |
{ |
{ |
382 |
this.rawOffset = rawOffset; |
this.rawOffset = rawOffset; |
383 |
setID(id); |
setID(id); |
390 |
this.startTimeMode = startTimeMode; |
this.startTimeMode = startTimeMode; |
391 |
this.endTimeMode = endTimeMode; |
this.endTimeMode = endTimeMode; |
392 |
|
|
393 |
setStartRule(startMonth, startDayOfWeekInMonth, |
setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime); |
|
startDayOfWeek, startTime); |
|
394 |
setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); |
setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime); |
395 |
if (startMonth == endMonth) |
if (startMonth == endMonth) |
396 |
throw new IllegalArgumentException |
throw new IllegalArgumentException("startMonth and endMonth must be different"); |
|
("startMonth and endMonth must be different"); |
|
397 |
this.startYear = 0; |
this.startYear = 0; |
398 |
|
|
399 |
this.dstSavings = dstSavings; |
this.dstSavings = dstSavings; |
454 |
} |
} |
455 |
} |
} |
456 |
|
|
|
|
|
457 |
/** |
/** |
458 |
* Sets the daylight savings start rule. You must also set the |
* Sets the daylight savings start rule. You must also set the |
459 |
* end rule with <code>setEndRule</code> or the result of |
* end rule with <code>setEndRule</code> or the result of |
507 |
* @since 1.2 |
* @since 1.2 |
508 |
* @see SimpleTimeZone |
* @see SimpleTimeZone |
509 |
*/ |
*/ |
510 |
public void setStartRule(int month, int day, int dayOfWeek, int time, boolean after) |
public void setStartRule(int month, int day, int dayOfWeek, int time, |
511 |
|
boolean after) |
512 |
{ |
{ |
513 |
// FIXME: XXX: Validate that checkRule and offset processing work with on |
// FIXME: XXX: Validate that checkRule and offset processing work with on |
514 |
// or before mode. |
// or before mode. |
515 |
this.startDay = after ? Math.abs(day) : -Math.abs(day); |
this.startDay = after ? Math.abs(day) : -Math.abs(day); |
516 |
this.startDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek); |
this.startDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek); |
517 |
this.startMode = (dayOfWeek != 0) ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE) |
this.startMode = (dayOfWeek != 0) |
518 |
: checkRule(month, day, dayOfWeek); |
? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE) |
519 |
|
: checkRule(month, day, dayOfWeek); |
520 |
this.startDay = Math.abs(this.startDay); |
this.startDay = Math.abs(this.startDay); |
521 |
this.startDayOfWeek = Math.abs(this.startDayOfWeek); |
this.startDayOfWeek = Math.abs(this.startDayOfWeek); |
522 |
|
|
601 |
* @since 1.2 |
* @since 1.2 |
602 |
* @see #setStartRule |
* @see #setStartRule |
603 |
*/ |
*/ |
604 |
public void setEndRule(int month, int day, int dayOfWeek, int time, boolean after) |
public void setEndRule(int month, int day, int dayOfWeek, int time, |
605 |
|
boolean after) |
606 |
{ |
{ |
607 |
// FIXME: XXX: Validate that checkRule and offset processing work with on |
// FIXME: XXX: Validate that checkRule and offset processing work with on |
608 |
// or before mode. |
// or before mode. |
609 |
this.endDay = after ? Math.abs(day) : -Math.abs(day); |
this.endDay = after ? Math.abs(day) : -Math.abs(day); |
610 |
this.endDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek); |
this.endDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek); |
611 |
this.endMode = (dayOfWeek != 0) ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE) |
this.endMode = (dayOfWeek != 0) |
612 |
: checkRule(month, day, dayOfWeek); |
? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE) |
613 |
|
: checkRule(month, day, dayOfWeek); |
614 |
this.endDay = Math.abs(this.endDay); |
this.endDay = Math.abs(this.endDay); |
615 |
this.endDayOfWeek = Math.abs(endDayOfWeek); |
this.endDayOfWeek = Math.abs(endDayOfWeek); |
616 |
|
|
645 |
} |
} |
646 |
|
|
647 |
/** |
/** |
648 |
* Gets the time zone offset, for current date, modified in case of |
* Gets the time zone offset, for current date, modified in case of |
649 |
* daylight savings. This is the offset to add to UTC to get the local |
* daylight savings. This is the offset to add to UTC to get the local |
650 |
* time. |
* time. |
651 |
* |
* |
671 |
* @return the time zone offset in milliseconds. |
* @return the time zone offset in milliseconds. |
672 |
* @throws IllegalArgumentException if arguments are incorrect. |
* @throws IllegalArgumentException if arguments are incorrect. |
673 |
*/ |
*/ |
674 |
public int getOffset(int era, int year, int month, |
public int getOffset(int era, int year, int month, int day, int dayOfWeek, |
675 |
int day, int dayOfWeek, int millis) |
int millis) |
676 |
{ |
{ |
677 |
int daysInMonth = getDaysInMonth(month, year); |
int daysInMonth = getDaysInMonth(month, year); |
678 |
if (day < 1 || day > daysInMonth) |
if (day < 1 || day > daysInMonth) |
688 |
{ |
{ |
689 |
// This does only work for Gregorian calendars :-( |
// This does only work for Gregorian calendars :-( |
690 |
// This is mainly because setStartYear doesn't take an era. |
// This is mainly because setStartYear doesn't take an era. |
691 |
|
boolean afterStart = ! isBefore(year, month, day, dayOfWeek, millis, |
692 |
boolean afterStart = !isBefore(year, month, day, dayOfWeek, millis, |
startMode, startMonth, startDay, |
693 |
startMode, startMonth, |
startDayOfWeek, startTime); |
|
startDay, startDayOfWeek, startTime); |
|
694 |
boolean beforeEnd = isBefore(year, month, day, dayOfWeek, |
boolean beforeEnd = isBefore(year, month, day, dayOfWeek, |
695 |
millis + dstSavings, |
millis + dstSavings, endMode, endMonth, |
696 |
endMode, endMonth, |
endDay, endDayOfWeek, endTime); |
|
endDay, endDayOfWeek, endTime); |
|
697 |
|
|
698 |
if (startMonth < endMonth) |
if (startMonth < endMonth) |
699 |
{ |
// use daylight savings, if the date is after the start of |
700 |
// use daylight savings, if the date is after the start of |
// savings, and before the end of savings. |
701 |
// savings, and before the end of savings. |
daylightSavings = afterStart && beforeEnd ? dstSavings : 0; |
|
daylightSavings = afterStart && beforeEnd ? dstSavings : 0; |
|
|
} |
|
702 |
else |
else |
703 |
{ |
// use daylight savings, if the date is before the end of |
704 |
// use daylight savings, if the date is before the end of |
// savings, or after the start of savings. |
705 |
// savings, or after the start of savings. |
daylightSavings = beforeEnd || afterStart ? dstSavings : 0; |
|
daylightSavings = beforeEnd || afterStart ? dstSavings : 0; |
|
|
} |
|
706 |
} |
} |
707 |
return rawOffset + daylightSavings; |
return rawOffset + daylightSavings; |
708 |
} |
} |
731 |
* milliseconds with respect to standard time. Typically this |
* milliseconds with respect to standard time. Typically this |
732 |
* is one hour, but for some time zones this may be half an our. |
* is one hour, but for some time zones this may be half an our. |
733 |
* @return the daylight savings offset in milliseconds. |
* @return the daylight savings offset in milliseconds. |
734 |
* |
* |
735 |
* @since 1.2 |
* @since 1.2 |
736 |
*/ |
*/ |
737 |
public int getDSTSavings() |
public int getDSTSavings() |
751 |
{ |
{ |
752 |
if (dstSavings <= 0) |
if (dstSavings <= 0) |
753 |
throw new IllegalArgumentException("illegal value for dstSavings"); |
throw new IllegalArgumentException("illegal value for dstSavings"); |
754 |
|
|
755 |
this.dstSavings = dstSavings; |
this.dstSavings = dstSavings; |
756 |
} |
} |
757 |
|
|
766 |
|
|
767 |
/** |
/** |
768 |
* Returns the number of days in the given month. It does always |
* Returns the number of days in the given month. It does always |
769 |
* use the Gregorian leap year rule. |
* use the Gregorian leap year rule. |
770 |
* @param month The month, zero based; use one of the Calendar constants. |
* @param month The month, zero based; use one of the Calendar constants. |
771 |
* @param year The year. |
* @param year The year. |
772 |
*/ |
*/ |
774 |
{ |
{ |
775 |
// Most of this is copied from GregorianCalendar.getActualMaximum() |
// Most of this is copied from GregorianCalendar.getActualMaximum() |
776 |
if (month == Calendar.FEBRUARY) |
if (month == Calendar.FEBRUARY) |
777 |
{ |
return ((year & 3) == 0 && (year % 100 != 0 || year % 400 == 0)) ? 29 : 28; |
|
return ((year & 3) == 0 && (year % 100 != 0 || year % 400 == 0)) |
|
|
? 29 : 28; |
|
|
} |
|
778 |
else if (month < Calendar.AUGUST) |
else if (month < Calendar.AUGUST) |
779 |
return 31 - (month & 1); |
return 31 - (month & 1); |
780 |
else |
else |
781 |
return 30 + (month & 1); |
return 30 + (month & 1); |
782 |
} |
} |
792 |
* @param mode the change mode; same semantic as startMode. |
* @param mode the change mode; same semantic as startMode. |
793 |
* @param month the change month; same semantic as startMonth. |
* @param month the change month; same semantic as startMonth. |
794 |
* @param day the change day; same semantic as startDay. |
* @param day the change day; same semantic as startDay. |
795 |
* @param dayOfWeek the change day of week; |
* @param dayOfWeek the change day of week; |
796 |
* @param millis the change time in millis since midnight standard time. |
* @param millis the change time in millis since midnight standard time. |
797 |
* same semantic as startDayOfWeek. |
* same semantic as startDayOfWeek. |
798 |
* @return true, if cal is before the change, false if cal is on |
* @return true, if cal is before the change, false if cal is on |
799 |
* or after the change. |
* or after the change. |
800 |
*/ |
*/ |
801 |
private boolean isBefore(int calYear, |
private boolean isBefore(int calYear, int calMonth, int calDayOfMonth, |
802 |
int calMonth, int calDayOfMonth, int calDayOfWeek, |
int calDayOfWeek, int calMillis, int mode, |
803 |
int calMillis, int mode, int month, |
int month, int day, int dayOfWeek, int millis) |
|
int day, int dayOfWeek, int millis) |
|
804 |
{ |
{ |
|
|
|
805 |
// This method is called by Calendar, so we mustn't use that class. |
// This method is called by Calendar, so we mustn't use that class. |
806 |
// We have to do all calculations by hand. |
// We have to do all calculations by hand. |
|
|
|
807 |
// check the months: |
// check the months: |
|
|
|
808 |
// XXX - this is not correct: |
// XXX - this is not correct: |
809 |
// for the DOW_GE_DOM and DOW_LE_DOM modes the change date may |
// for the DOW_GE_DOM and DOW_LE_DOM modes the change date may |
810 |
// be in a different month. |
// be in a different month. |
819 |
return calDayOfMonth < day; |
return calDayOfMonth < day; |
820 |
break; |
break; |
821 |
case DOW_IN_MONTH_MODE: |
case DOW_IN_MONTH_MODE: |
822 |
{ |
{ |
823 |
// This computes the day of month of the day of type |
// This computes the day of month of the day of type |
824 |
// "dayOfWeek" that lies in the same (sunday based) week as cal. |
// "dayOfWeek" that lies in the same (sunday based) week as cal. |
825 |
calDayOfMonth += (dayOfWeek - calDayOfWeek); |
calDayOfMonth += (dayOfWeek - calDayOfWeek); |
828 |
// after dividing by 7). If we count from the end of the |
// after dividing by 7). If we count from the end of the |
829 |
// month, we get want a -7 based number counting the days from |
// month, we get want a -7 based number counting the days from |
830 |
// the end: |
// the end: |
|
|
|
831 |
if (day < 0) |
if (day < 0) |
832 |
calDayOfMonth -= getDaysInMonth(calMonth, calYear) + 7; |
calDayOfMonth -= getDaysInMonth(calMonth, calYear) + 7; |
833 |
else |
else |
840 |
// 20 21 22 23 24 25 26 -23-22-21-20-19-18-17 |
// 20 21 22 23 24 25 26 -23-22-21-20-19-18-17 |
841 |
// 27 28 29 30 31 32 33 -16-15-14-13-12-11-10 |
// 27 28 29 30 31 32 33 -16-15-14-13-12-11-10 |
842 |
// 34 35 36 -9 -8 -7 |
// 34 35 36 -9 -8 -7 |
|
|
|
843 |
// Now we calculate the day of week in month: |
// Now we calculate the day of week in month: |
844 |
int week = calDayOfMonth / 7; |
int week = calDayOfMonth / 7; |
845 |
|
|
846 |
// day > 0 day < 0 |
// day > 0 day < 0 |
847 |
// S M T W T F S S M T W T F S |
// S M T W T F S S M T W T F S |
848 |
// 1 1 1 1 1 1 -5 -5 -4 -4 -4 -4 |
// 1 1 1 1 1 1 -5 -5 -4 -4 -4 -4 |
850 |
// 2 3 3 3 3 3 3 -3 -3 -3 -2 -2 -2 -2 |
// 2 3 3 3 3 3 3 -3 -3 -3 -2 -2 -2 -2 |
851 |
// 3 4 4 4 4 4 4 -2 -2 -2 -1 -1 -1 -1 |
// 3 4 4 4 4 4 4 -2 -2 -2 -1 -1 -1 -1 |
852 |
// 4 5 5 -1 -1 -1 |
// 4 5 5 -1 -1 -1 |
|
|
|
853 |
if (week != day) |
if (week != day) |
854 |
return week < day; |
return week < day; |
855 |
|
|
858 |
|
|
859 |
// daylight savings starts/ends on the given day. |
// daylight savings starts/ends on the given day. |
860 |
break; |
break; |
861 |
} |
} |
|
|
|
862 |
case DOW_LE_DOM_MODE: |
case DOW_LE_DOM_MODE: |
863 |
// The greatest sunday before or equal December, 12 |
// The greatest sunday before or equal December, 12 |
864 |
// is the same as smallest sunday after or equal December, 6. |
// is the same as smallest sunday after or equal December, 6. |
865 |
day = Math.abs(day) - 6; |
day = Math.abs(day) - 6; |
|
|
|
866 |
case DOW_GE_DOM_MODE: |
case DOW_GE_DOM_MODE: |
|
|
|
867 |
// Calculate the day of month of the day of type |
// Calculate the day of month of the day of type |
868 |
// "dayOfWeek" that lies before (or on) the given date. |
// "dayOfWeek" that lies before (or on) the given date. |
869 |
calDayOfMonth -= (calDayOfWeek < dayOfWeek ? 7 : 0) |
calDayOfMonth -= (calDayOfWeek < dayOfWeek ? 7 : 0) + calDayOfWeek |
870 |
+ calDayOfWeek - dayOfWeek; |
- dayOfWeek; |
871 |
if (calDayOfMonth < day) |
if (calDayOfMonth < day) |
872 |
return true; |
return true; |
873 |
if (calDayOfWeek != dayOfWeek || calDayOfMonth >= day + 7) |
if (calDayOfWeek != dayOfWeek || calDayOfMonth >= day + 7) |
874 |
return false; |
return false; |
875 |
|
|
876 |
// now we have the same day |
// now we have the same day |
877 |
break; |
break; |
878 |
} |
} |
879 |
|
|
880 |
// the millis decides: |
// the millis decides: |
881 |
return (calMillis < millis); |
return (calMillis < millis); |
882 |
} |
} |
895 |
/** |
/** |
896 |
* Generates the hashCode for the SimpleDateFormat object. It is |
* Generates the hashCode for the SimpleDateFormat object. It is |
897 |
* the rawOffset, possibly, if useDaylightSavings is true, xored |
* the rawOffset, possibly, if useDaylightSavings is true, xored |
898 |
* with startYear, startMonth, startDayOfWeekInMonth, ..., endTime. |
* with startYear, startMonth, startDayOfWeekInMonth, ..., endTime. |
899 |
*/ |
*/ |
900 |
public synchronized int hashCode() |
public synchronized int hashCode() |
901 |
{ |
{ |
902 |
return rawOffset ^ |
return rawOffset |
903 |
(useDaylight ? |
^ (useDaylight |
904 |
startMonth ^ startDay ^ startDayOfWeek ^ startTime |
? startMonth ^ startDay ^ startDayOfWeek ^ startTime ^ endMonth |
905 |
^ endMonth ^ endDay ^ endDayOfWeek ^ endTime : 0); |
^ endDay ^ endDayOfWeek ^ endTime : 0); |
906 |
} |
} |
907 |
|
|
908 |
public synchronized boolean equals(Object o) |
public synchronized boolean equals(Object o) |
909 |
{ |
{ |
910 |
if (this == o) |
if (this == o) |
911 |
return true; |
return true; |
912 |
if (!(o instanceof SimpleTimeZone)) |
if (! (o instanceof SimpleTimeZone)) |
913 |
return false; |
return false; |
914 |
SimpleTimeZone zone = (SimpleTimeZone) o; |
SimpleTimeZone zone = (SimpleTimeZone) o; |
915 |
if (zone.hashCode() != hashCode() |
if (zone.hashCode() != hashCode() || ! getID().equals(zone.getID()) |
916 |
|| !getID().equals(zone.getID()) |
|| rawOffset != zone.rawOffset || useDaylight != zone.useDaylight) |
|
|| rawOffset != zone.rawOffset || useDaylight != zone.useDaylight) |
|
917 |
return false; |
return false; |
918 |
if (!useDaylight) |
if (! useDaylight) |
919 |
return true; |
return true; |
920 |
return (startYear == zone.startYear |
return (startYear == zone.startYear && startMonth == zone.startMonth |
921 |
&& startMonth == zone.startMonth |
&& startDay == zone.startDay |
922 |
&& startDay == zone.startDay |
&& startDayOfWeek == zone.startDayOfWeek |
923 |
&& startDayOfWeek == zone.startDayOfWeek |
&& startTime == zone.startTime |
924 |
&& startTime == zone.startTime |
&& startTimeMode == zone.startTimeMode && endMonth == zone.endMonth |
925 |
&& startTimeMode == zone.startTimeMode |
&& endDay == zone.endDay && endDayOfWeek == zone.endDayOfWeek |
926 |
&& endMonth == zone.endMonth |
&& endTime == zone.endTime && endTimeMode == zone.endTimeMode); |
|
&& endDay == zone.endDay |
|
|
&& endDayOfWeek == zone.endDayOfWeek |
|
|
&& endTime == zone.endTime |
|
|
&& endTimeMode == zone.endTimeMode); |
|
927 |
} |
} |
928 |
|
|
929 |
/** |
/** |
938 |
{ |
{ |
939 |
if (this == other) |
if (this == other) |
940 |
return true; |
return true; |
941 |
if (!(other instanceof SimpleTimeZone)) |
if (! (other instanceof SimpleTimeZone)) |
942 |
return false; |
return false; |
943 |
SimpleTimeZone zone = (SimpleTimeZone) other; |
SimpleTimeZone zone = (SimpleTimeZone) other; |
944 |
if (zone.hashCode() != hashCode() |
if (zone.hashCode() != hashCode() || rawOffset != zone.rawOffset |
945 |
|| rawOffset != zone.rawOffset || useDaylight != zone.useDaylight) |
|| useDaylight != zone.useDaylight) |
946 |
return false; |
return false; |
947 |
if (!useDaylight) |
if (! useDaylight) |
948 |
return true; |
return true; |
949 |
return (startYear == zone.startYear |
return (startYear == zone.startYear && startMonth == zone.startMonth |
950 |
&& startMonth == zone.startMonth |
&& startDay == zone.startDay |
951 |
&& startDay == zone.startDay |
&& startDayOfWeek == zone.startDayOfWeek |
952 |
&& startDayOfWeek == zone.startDayOfWeek |
&& startTime == zone.startTime |
953 |
&& startTime == zone.startTime |
&& startTimeMode == zone.startTimeMode && endMonth == zone.endMonth |
954 |
&& startTimeMode == zone.startTimeMode |
&& endDay == zone.endDay && endDayOfWeek == zone.endDayOfWeek |
955 |
&& endMonth == zone.endMonth |
&& endTime == zone.endTime && endTimeMode == zone.endTimeMode); |
|
&& endDay == zone.endDay |
|
|
&& endDayOfWeek == zone.endDayOfWeek |
|
|
&& endTime == zone.endTime |
|
|
&& endTimeMode == zone.endTimeMode); |
|
956 |
} |
} |
957 |
|
|
958 |
/** |
/** |
963 |
{ |
{ |
964 |
// the test for useDaylight is an incompatibility to jdk1.2, but |
// the test for useDaylight is an incompatibility to jdk1.2, but |
965 |
// I think this shouldn't hurt. |
// I think this shouldn't hurt. |
966 |
return getClass().getName() + "[" |
return getClass().getName() + "[" + "id=" + getID() + ",offset=" |
967 |
+ "id=" + getID() |
+ rawOffset + ",dstSavings=" + dstSavings + ",useDaylight=" |
968 |
+ ",offset=" + rawOffset |
+ useDaylight |
969 |
+ ",dstSavings=" + dstSavings |
+ (useDaylight |
970 |
+ ",useDaylight=" + useDaylight |
? ",startYear=" + startYear + ",startMode=" + startMode |
971 |
+ (useDaylight ? |
+ ",startMonth=" + startMonth + ",startDay=" + startDay |
972 |
",startYear=" + startYear |
+ ",startDayOfWeek=" + startDayOfWeek + ",startTime=" |
973 |
+ ",startMode=" + startMode |
+ startTime + ",startTimeMode=" + startTimeMode + ",endMode=" |
974 |
+ ",startMonth=" + startMonth |
+ endMode + ",endMonth=" + endMonth + ",endDay=" + endDay |
975 |
+ ",startDay=" + startDay |
+ ",endDayOfWeek=" + endDayOfWeek + ",endTime=" + endTime |
976 |
+ ",startDayOfWeek=" + startDayOfWeek |
+ ",endTimeMode=" + endTimeMode : "") + "]"; |
|
+ ",startTime=" + startTime |
|
|
+ ",startTimeMode=" + startTimeMode |
|
|
+ ",endMode=" + endMode |
|
|
+ ",endMonth=" + endMonth |
|
|
+ ",endDay=" + endDay |
|
|
+ ",endDayOfWeek=" + endDayOfWeek |
|
|
+ ",endTime=" + endTime |
|
|
+ ",endTimeMode=" + endTimeMode |
|
|
: "") + "]"; |
|
977 |
} |
} |
978 |
|
|
979 |
/** |
/** |
992 |
startMode = DOW_IN_MONTH_MODE; |
startMode = DOW_IN_MONTH_MODE; |
993 |
startTimeMode = WALL_TIME; |
startTimeMode = WALL_TIME; |
994 |
endTimeMode = WALL_TIME; |
endTimeMode = WALL_TIME; |
995 |
serialVersionOnStream = 2; } |
serialVersionOnStream = 2; |
996 |
|
} |
997 |
else |
else |
998 |
{ |
{ |
999 |
int length = input.readInt(); |
int length = input.readInt(); |
1018 |
* <code>start/endDay(OfWeek)</code>-Fields are written in the |
* <code>start/endDay(OfWeek)</code>-Fields are written in the |
1019 |
* DOW_IN_MONTH_MODE rule, since this was the only supported rule |
* DOW_IN_MONTH_MODE rule, since this was the only supported rule |
1020 |
* in 1.1. |
* in 1.1. |
1021 |
* |
* |
1022 |
* In the optional section, we write first the length of an byte |
* In the optional section, we write first the length of an byte |
1023 |
* array as int and afterwards the byte array itself. The byte |
* array as int and afterwards the byte array itself. The byte |
1024 |
* array contains in this release four elements, namely the real |
* array contains in this release four elements, namely the real |
1025 |
* startDay, startDayOfWeek endDay, endDayOfWeek in that Order. |
* startDay, startDayOfWeek endDay, endDayOfWeek in that Order. |
1026 |
* These fields are needed, because for compatibility reasons only |
* These fields are needed, because for compatibility reasons only |
1027 |
* approximative values are written to the required section, as |
* approximative values are written to the required section, as |
1028 |
* described above. |
* described above. |
1029 |
*/ |
*/ |
1030 |
private void writeObject(java.io.ObjectOutputStream output) |
private void writeObject(java.io.ObjectOutputStream output) |
1031 |
throws java.io.IOException |
throws java.io.IOException |
1032 |
{ |
{ |
1033 |
byte[] byteArray = new byte[] |
byte[] byteArray = new byte[] |
1034 |
{ |
{ |
1035 |
(byte) startDay, (byte) startDayOfWeek, |
(byte) startDay, (byte) startDayOfWeek, (byte) endDay, |
1036 |
(byte) endDay, (byte) endDayOfWeek}; |
(byte) endDayOfWeek |
1037 |
|
}; |
1038 |
|
|
1039 |
/* calculate the approximation for JDK 1.1 */ |
/* calculate the approximation for JDK 1.1 */ |
1040 |
switch (startMode) |
switch (startMode) |
1041 |
{ |
{ |
1042 |
case DOM_MODE: |
case DOM_MODE: |
1043 |
startDayOfWeek = Calendar.SUNDAY; // random day of week |
startDayOfWeek = Calendar.SUNDAY; // random day of week |
1044 |
// fall through |
|
1045 |
|
// fall through |
1046 |
case DOW_GE_DOM_MODE: |
case DOW_GE_DOM_MODE: |
1047 |
case DOW_LE_DOM_MODE: |
case DOW_LE_DOM_MODE: |
1048 |
startDay = (startDay + 6) / 7; |
startDay = (startDay + 6) / 7; |
1051 |
{ |
{ |
1052 |
case DOM_MODE: |
case DOM_MODE: |
1053 |
endDayOfWeek = Calendar.SUNDAY; |
endDayOfWeek = Calendar.SUNDAY; |
1054 |
// fall through |
|
1055 |
|
// fall through |
1056 |
case DOW_GE_DOM_MODE: |
case DOW_GE_DOM_MODE: |
1057 |
case DOW_LE_DOM_MODE: |
case DOW_LE_DOM_MODE: |
1058 |
endDay = (endDay + 6) / 7; |
endDay = (endDay + 6) / 7; |