001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.util;
019:
020: import java.io.IOException;
021: import java.io.ObjectInputStream;
022: import java.io.ObjectOutputStream;
023: import java.io.ObjectStreamField;
024:
025: import org.apache.harmony.luni.util.Msg;
026:
027: /**
028: * SimpleTimeZone represents a local time zone and its daylight savings time
029: * rules for the gregorian calendar.
030: *
031: * @see Calendar
032: * @see TimeZone
033: */
034: public class SimpleTimeZone extends TimeZone {
035:
036: private static final long serialVersionUID = -403250971215465050L;
037:
038: private int rawOffset;
039:
040: private int startYear, startMonth, startDay, startDayOfWeek,
041: startTime;
042:
043: private int endMonth, endDay, endDayOfWeek, endTime;
044:
045: private int startMode, endMode;
046:
047: private static final int DOM_MODE = 1, DOW_IN_MONTH_MODE = 2,
048: DOW_GE_DOM_MODE = 3, DOW_LE_DOM_MODE = 4;
049:
050: /* Constant for representing start or end time in GMT time mode. */
051: public static final int UTC_TIME = 2;
052:
053: /*
054: * Constant for representing start or end time in standard local time mode,
055: * based on timezone's raw offset from GMT, does not include Daylight
056: * savings.
057: */
058: public static final int STANDARD_TIME = 1;
059:
060: /*
061: * Constant for representing start or end time in local wall clock time
062: * mode, based on timezone's adjusted offset from GMT, it does include
063: * Daylight savings.
064: */
065: public static final int WALL_TIME = 0;
066:
067: private boolean useDaylight;
068:
069: private GregorianCalendar daylightSavings;
070:
071: private int dstSavings = 3600000;
072:
073: private transient com.ibm.icu.util.TimeZone icuTZ;
074:
075: private boolean isSimple;
076:
077: /**
078: * Constructs a new SimpleTimeZone using the specified offset for standard
079: * time from GMT and the specified time zone ID.
080: *
081: * @param offset
082: * the offset from GMT of standard time in milliseconds
083: * @param name
084: * the time zone ID
085: */
086: public SimpleTimeZone(int offset, String name) {
087: setID(name);
088: rawOffset = offset;
089: icuTZ = com.ibm.icu.util.TimeZone.getTimeZone(name);
090: if (icuTZ instanceof com.ibm.icu.util.SimpleTimeZone) {
091: isSimple = true;
092: icuTZ.setRawOffset(offset);
093: }
094: useDaylight = icuTZ.useDaylightTime();
095: }
096:
097: /**
098: * Constructs a new SimpleTimeZone using the specified offset for standard
099: * time from GMT, the specified time zone ID and the rules for daylight
100: * savings time.
101: *
102: * @param offset
103: * the offset from GMT of standard time in milliseconds
104: * @param name
105: * the time zone ID
106: * @param startMonth
107: * the Calendar month in which daylight savings time starts
108: * @param startDay
109: * the occurrence of the day of the week on which daylight
110: * savings time starts
111: * @param startDayOfWeek
112: * the Calendar day of the week on which daylight savings time
113: * starts
114: * @param startTime
115: * the time of day in milliseconds on which daylight savings time
116: * starts
117: * @param endMonth
118: * the Calendar month in which daylight savings time ends
119: * @param endDay
120: * the occurrence of the day of the week on which daylight
121: * savings time ends
122: * @param endDayOfWeek
123: * the Calendar day of the week on which daylight savings time
124: * ends
125: * @param endTime
126: * the time of day in milliseconds standard time on which
127: * daylight savings time ends
128: */
129: public SimpleTimeZone(int offset, String name, int startMonth,
130: int startDay, int startDayOfWeek, int startTime,
131: int endMonth, int endDay, int endDayOfWeek, int endTime) {
132: this (offset, name, startMonth, startDay, startDayOfWeek,
133: startTime, endMonth, endDay, endDayOfWeek, endTime,
134: 3600000);
135: }
136:
137: /**
138: * Constructs a new SimpleTimeZone using the specified offset for standard
139: * time from GMT, the specified time zone ID and the rules for daylight
140: * savings time.
141: *
142: * @param offset
143: * the offset from GMT of standard time in milliseconds
144: * @param name
145: * the time zone ID
146: * @param startMonth
147: * the Calendar month in which daylight savings time starts
148: * @param startDay
149: * the occurrence of the day of the week on which daylight
150: * savings time starts
151: * @param startDayOfWeek
152: * the Calendar day of the week on which daylight savings time
153: * starts
154: * @param startTime
155: * the time of day in milliseconds on which daylight savings time
156: * starts
157: * @param endMonth
158: * the Calendar month in which daylight savings time ends
159: * @param endDay
160: * the occurrence of the day of the week on which daylight
161: * savings time ends
162: * @param endDayOfWeek
163: * the Calendar day of the week on which daylight savings time
164: * ends
165: * @param endTime
166: * the time of day in milliseconds standard time on which
167: * daylight savings time ends
168: * @param daylightSavings
169: * the daylight savings time difference in milliseconds
170: */
171: public SimpleTimeZone(int offset, String name, int startMonth,
172: int startDay, int startDayOfWeek, int startTime,
173: int endMonth, int endDay, int endDayOfWeek, int endTime,
174: int daylightSavings) {
175: icuTZ = com.ibm.icu.util.TimeZone.getTimeZone(name);
176: if (icuTZ instanceof com.ibm.icu.util.SimpleTimeZone) {
177: isSimple = true;
178: com.ibm.icu.util.SimpleTimeZone tz = (com.ibm.icu.util.SimpleTimeZone) icuTZ;
179: tz.setRawOffset(offset);
180: tz.setStartRule(startMonth, startDay, startDayOfWeek,
181: startTime);
182: tz.setEndRule(endMonth, endDay, endDayOfWeek, endTime);
183: tz.setDSTSavings(daylightSavings);
184: }
185: setID(name);
186: rawOffset = offset;
187: if (daylightSavings <= 0) {
188: throw new IllegalArgumentException(Msg.getString(
189: "K00e9", daylightSavings)); //$NON-NLS-1$
190: }
191: dstSavings = daylightSavings;
192:
193: setStartRule(startMonth, startDay, startDayOfWeek, startTime);
194: setEndRule(endMonth, endDay, endDayOfWeek, endTime);
195:
196: useDaylight = daylightSavings > 0 || icuTZ.useDaylightTime();
197: }
198:
199: /**
200: * Constructs a new SimpleTimeZone using the specified offset for standard
201: * time from GMT, the specified time zone ID, the rules for daylight savings
202: * time, and the modes indicating UTC, standard, or wall time.
203: *
204: * @param offset
205: * the offset from GMT of standard time in milliseconds
206: * @param name
207: * the time zone ID
208: * @param startMonth
209: * the Calendar month in which daylight savings time starts
210: * @param startDay
211: * the occurrence of the day of the week on which daylight
212: * savings time starts
213: * @param startDayOfWeek
214: * the Calendar day of the week on which daylight savings time
215: * starts
216: * @param startTime
217: * the time of day in milliseconds on which daylight savings time
218: * starts
219: * @param startTimeMode
220: * the mode (UTC, standard, or wall time) of the start time value
221: * @param endMonth
222: * the Calendar month in which daylight savings time ends
223: * @param endDay
224: * the occurrence of the day of the week on which daylight
225: * savings time ends
226: * @param endDayOfWeek
227: * the Calendar day of the week on which daylight savings time
228: * ends
229: * @param endTime
230: * the time of day in milliseconds standard time on which
231: * daylight savings time ends
232: * @param endTimeMode
233: * the mode (UTC, standard, or wall time) of the end time value
234: * @param daylightSavings
235: * the daylight savings time difference in milliseconds
236: */
237: public SimpleTimeZone(int offset, String name, int startMonth,
238: int startDay, int startDayOfWeek, int startTime,
239: int startTimeMode, int endMonth, int endDay,
240: int endDayOfWeek, int endTime, int endTimeMode,
241: int daylightSavings) {
242:
243: this (offset, name, startMonth, startDay, startDayOfWeek,
244: startTime, endMonth, endDay, endDayOfWeek, endTime,
245: daylightSavings);
246: startMode = startTimeMode;
247: endMode = endTimeMode;
248: }
249:
250: /**
251: * Answers a new SimpleTimeZone with the same ID, rawOffset and daylight
252: * savings time rules as this SimpleTimeZone.
253: *
254: * @return a shallow copy of this SimpleTimeZone
255: *
256: * @see java.lang.Cloneable
257: */
258: @Override
259: public Object clone() {
260: SimpleTimeZone zone = (SimpleTimeZone) super .clone();
261: if (daylightSavings != null) {
262: zone.daylightSavings = (GregorianCalendar) daylightSavings
263: .clone();
264: }
265: return zone;
266: }
267:
268: /**
269: * Compares the specified object to this SimpleTimeZone and answer if they
270: * are equal. The object must be an instance of SimpleTimeZone and have the
271: * same properties.
272: *
273: * @param object
274: * the object to compare with this object
275: * @return true if the specified object is equal to this SimpleTimeZone,
276: * false otherwise
277: *
278: * @see #hashCode
279: */
280: @Override
281: public boolean equals(Object object) {
282: if (!(object instanceof SimpleTimeZone)) {
283: return false;
284: }
285: SimpleTimeZone tz = (SimpleTimeZone) object;
286: return getID().equals(tz.getID())
287: && rawOffset == tz.rawOffset
288: && useDaylight == tz.useDaylight
289: && (!useDaylight || (startYear == tz.startYear
290: && startMonth == tz.startMonth
291: && startDay == tz.startDay
292: && startMode == tz.startMode
293: && startDayOfWeek == tz.startDayOfWeek
294: && startTime == tz.startTime
295: && endMonth == tz.endMonth
296: && endDay == tz.endDay
297: && endDayOfWeek == tz.endDayOfWeek
298: && endTime == tz.endTime
299: && endMode == tz.endMode && dstSavings == tz.dstSavings));
300: }
301:
302: /**
303: * Gets the daylight savings offset in milliseconds for this SimpleTimeZone.
304: *
305: * If this SimpleTimezone does not observe daylight savings, returns 0.
306: *
307: * @return the daylight savings offset in milliseconds
308: */
309: @Override
310: public int getDSTSavings() {
311: if (!useDaylight) {
312: return 0;
313: }
314: return dstSavings;
315: }
316:
317: /**
318: * Gets the offset from GMT of this SimpleTimeZone for the specified date
319: * and time. The offset includes daylight savings time if the specified date
320: * and time are within the daylight savings time period.
321: *
322: * @param era
323: * the GregorianCalendar era, either GregorianCalendar.BC or
324: * GregorianCalendar.AD
325: * @param year
326: * the year
327: * @param month
328: * the Calendar month
329: * @param day
330: * the day of the month
331: * @param dayOfWeek
332: * the Calendar day of the week
333: * @param time
334: * the time of day in milliseconds
335: * @return the offset from GMT in milliseconds
336: */
337: @Override
338: public int getOffset(int era, int year, int month, int day,
339: int dayOfWeek, int time) {
340: if (era != GregorianCalendar.BC && era != GregorianCalendar.AD) {
341: throw new IllegalArgumentException(Msg.getString(
342: "K00ea", era)); //$NON-NLS-1$
343: }
344: checkRange(month, dayOfWeek, time);
345: if (month != Calendar.FEBRUARY || day != 29
346: || !isLeapYear(year)) {
347: checkDay(month, day);
348: }
349: return icuTZ.getOffset(era, year, month, day, dayOfWeek, time);
350: }
351:
352: /**
353: * Gets the offset from GMT of this SimpleTimeZone for the specified date.
354: * The offset includes daylight savings time if the specified date is within
355: * the daylight savings time period.
356: *
357: * @param time
358: * the date in milliseconds since January 1, 1970 00:00:00 GMT
359: * @return the offset from GMT in milliseconds
360: */
361: @Override
362: public int getOffset(long time) {
363: return icuTZ.getOffset(time);
364: }
365:
366: /**
367: * Gets the offset for standard time from GMT for this SimpleTimeZone.
368: *
369: * @return the offset from GMT of standard time in milliseconds
370: */
371: @Override
372: public int getRawOffset() {
373: return rawOffset;
374: }
375:
376: /**
377: * Answers an integer hash code for the receiver. Objects which are equal
378: * answer the same value for this method.
379: *
380: * @return the receiver's hash
381: *
382: * @see #equals
383: */
384: @Override
385: public synchronized int hashCode() {
386: int hashCode = getID().hashCode() + rawOffset;
387: if (useDaylight) {
388: hashCode += startYear + startMonth + startDay
389: + startDayOfWeek + startTime + startMode + endMonth
390: + endDay + endDayOfWeek + endTime + endMode
391: + dstSavings;
392: }
393: return hashCode;
394: }
395:
396: /**
397: * Answers if the specified TimeZone has the same raw offset and daylight
398: * savings time rules as this SimpleTimeZone.
399: *
400: * @param zone
401: * a TimeZone
402: * @return true when the TimeZones have the same raw offset and daylight
403: * savings time rules, false otherwise
404: */
405: @Override
406: public boolean hasSameRules(TimeZone zone) {
407: if (!(zone instanceof SimpleTimeZone)) {
408: return false;
409: }
410: SimpleTimeZone tz = (SimpleTimeZone) zone;
411: if (useDaylight != tz.useDaylight) {
412: return false;
413: }
414: if (!useDaylight) {
415: return rawOffset == tz.rawOffset;
416: }
417: return rawOffset == tz.rawOffset && dstSavings == tz.dstSavings
418: && startYear == tz.startYear
419: && startMonth == tz.startMonth
420: && startDay == tz.startDay && startMode == tz.startMode
421: && startDayOfWeek == tz.startDayOfWeek
422: && startTime == tz.startTime && endMonth == tz.endMonth
423: && endDay == tz.endDay
424: && endDayOfWeek == tz.endDayOfWeek
425: && endTime == tz.endTime && endMode == tz.endMode;
426: }
427:
428: /**
429: * Answers if the specified Date is in the daylight savings time period for
430: * this SimpleTimeZone.
431: *
432: * @param time
433: * a Date
434: * @return true when the Date is in the daylight savings time period, false
435: * otherwise
436: */
437: @Override
438: public boolean inDaylightTime(Date time) {
439: return icuTZ.inDaylightTime(time);
440: }
441:
442: private boolean isLeapYear(int year) {
443: if (year > 1582) {
444: return year % 4 == 0
445: && (year % 100 != 0 || year % 400 == 0);
446: }
447: return year % 4 == 0;
448: }
449:
450: /**
451: * Sets the daylight savings offset in milliseconds for this SimpleTimeZone.
452: *
453: * @param milliseconds
454: * the daylight savings offset in milliseconds
455: */
456: public void setDSTSavings(int milliseconds) {
457: if (milliseconds > 0) {
458: dstSavings = milliseconds;
459: } else {
460: throw new IllegalArgumentException();
461: }
462: }
463:
464: private void checkRange(int month, int dayOfWeek, int time) {
465: if (month < Calendar.JANUARY || month > Calendar.DECEMBER) {
466: throw new IllegalArgumentException(Msg.getString(
467: "K00e5", month)); //$NON-NLS-1$
468: }
469: if (dayOfWeek < Calendar.SUNDAY
470: || dayOfWeek > Calendar.SATURDAY) {
471: throw new IllegalArgumentException(Msg.getString(
472: "K00e7", dayOfWeek)); //$NON-NLS-1$
473: }
474: if (time < 0 || time >= 24 * 3600000) {
475: throw new IllegalArgumentException(Msg.getString(
476: "K00e8", time)); //$NON-NLS-1$
477: }
478: }
479:
480: private void checkDay(int month, int day) {
481: if (day <= 0 || day > GregorianCalendar.DaysInMonth[month]) {
482: throw new IllegalArgumentException(Msg.getString(
483: "K00e6", day)); //$NON-NLS-1$
484: }
485: }
486:
487: private void setEndMode() {
488: if (endDayOfWeek == 0) {
489: endMode = DOM_MODE;
490: } else if (endDayOfWeek < 0) {
491: endDayOfWeek = -endDayOfWeek;
492: if (endDay < 0) {
493: endDay = -endDay;
494: endMode = DOW_LE_DOM_MODE;
495: } else {
496: endMode = DOW_GE_DOM_MODE;
497: }
498: } else {
499: endMode = DOW_IN_MONTH_MODE;
500: }
501: useDaylight = startDay != 0 && endDay != 0;
502: if (endDay != 0) {
503: checkRange(endMonth,
504: endMode == DOM_MODE ? 1 : endDayOfWeek, endTime);
505: if (endMode != DOW_IN_MONTH_MODE) {
506: checkDay(endMonth, endDay);
507: } else {
508: if (endDay < -5 || endDay > 5) {
509: throw new IllegalArgumentException(Msg.getString(
510: "K00f8", endDay)); //$NON-NLS-1$
511: }
512: }
513: }
514: if (endMode != DOM_MODE) {
515: endDayOfWeek--;
516: }
517: }
518:
519: /**
520: * Sets the rule which specifies the end of daylight savings time.
521: *
522: * @param month
523: * the Calendar month in which daylight savings time ends
524: * @param dayOfMonth
525: * the Calendar day of the month on which daylight savings time
526: * ends
527: * @param time
528: * the time of day in milliseconds standard time on which
529: * daylight savings time ends
530: */
531: public void setEndRule(int month, int dayOfMonth, int time) {
532: endMonth = month;
533: endDay = dayOfMonth;
534: endDayOfWeek = 0; // Initialize this value for hasSameRules()
535: endTime = time;
536: setEndMode();
537: if (isSimple) {
538: ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month,
539: dayOfMonth, time);
540: }
541: }
542:
543: /**
544: * Sets the rule which specifies the end of daylight savings time.
545: *
546: * @param month
547: * the Calendar month in which daylight savings time ends
548: * @param day
549: * the occurrence of the day of the week on which daylight
550: * savings time ends
551: * @param dayOfWeek
552: * the Calendar day of the week on which daylight savings time
553: * ends
554: * @param time
555: * the time of day in milliseconds standard time on which
556: * daylight savings time ends
557: */
558: public void setEndRule(int month, int day, int dayOfWeek, int time) {
559: endMonth = month;
560: endDay = day;
561: endDayOfWeek = dayOfWeek;
562: endTime = time;
563: setEndMode();
564: if (isSimple) {
565: ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month,
566: day, dayOfWeek, time);
567: }
568: }
569:
570: /**
571: * Sets the rule which specifies the end of daylight savings time.
572: *
573: * @param month
574: * the Calendar month in which daylight savings time ends
575: * @param day
576: * the Calendar day of the month
577: * @param dayOfWeek
578: * the Calendar day of the week on which daylight savings time
579: * ends
580: * @param time
581: * the time of day in milliseconds on which daylight savings time
582: * ends
583: * @param after
584: * selects the day after or before the day of month
585: */
586: public void setEndRule(int month, int day, int dayOfWeek, int time,
587: boolean after) {
588: endMonth = month;
589: endDay = after ? day : -day;
590: endDayOfWeek = -dayOfWeek;
591: endTime = time;
592: setEndMode();
593: if (isSimple) {
594: ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setEndRule(month,
595: day, dayOfWeek, time, after);
596: }
597: }
598:
599: /**
600: * Sets the offset for standard time from GMT for this SimpleTimeZone.
601: *
602: * @param offset
603: * the offset from GMT of standard time in milliseconds
604: */
605: @Override
606: public void setRawOffset(int offset) {
607: rawOffset = offset;
608: icuTZ.setRawOffset(offset);
609: }
610:
611: private void setStartMode() {
612: if (startDayOfWeek == 0) {
613: startMode = DOM_MODE;
614: } else if (startDayOfWeek < 0) {
615: startDayOfWeek = -startDayOfWeek;
616: if (startDay < 0) {
617: startDay = -startDay;
618: startMode = DOW_LE_DOM_MODE;
619: } else {
620: startMode = DOW_GE_DOM_MODE;
621: }
622: } else {
623: startMode = DOW_IN_MONTH_MODE;
624: }
625: useDaylight = startDay != 0 && endDay != 0;
626: if (startDay != 0) {
627: checkRange(startMonth, startMode == DOM_MODE ? 1
628: : startDayOfWeek, startTime);
629: if (startMode != DOW_IN_MONTH_MODE) {
630: checkDay(startMonth, startDay);
631: } else {
632: if (startDay < -5 || startDay > 5) {
633: throw new IllegalArgumentException(Msg.getString(
634: "K00f8", startDay)); //$NON-NLS-1$
635: }
636: }
637: }
638: if (startMode != DOM_MODE) {
639: startDayOfWeek--;
640: }
641: }
642:
643: /**
644: * Sets the rule which specifies the start of daylight savings time.
645: *
646: * @param month
647: * the Calendar month in which daylight savings time starts
648: * @param dayOfMonth
649: * the Calendar day of the month on which daylight savings time
650: * starts
651: * @param time
652: * the time of day in milliseconds on which daylight savings time
653: * starts
654: */
655: public void setStartRule(int month, int dayOfMonth, int time) {
656: startMonth = month;
657: startDay = dayOfMonth;
658: startDayOfWeek = 0; // Initialize this value for hasSameRules()
659: startTime = time;
660: setStartMode();
661: if (isSimple) {
662: ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(
663: month, dayOfMonth, time);
664: }
665: }
666:
667: /**
668: * Sets the rule which specifies the start of daylight savings time.
669: *
670: * @param month
671: * the Calendar month in which daylight savings time starts
672: * @param day
673: * the occurrence of the day of the week on which daylight
674: * savings time starts
675: * @param dayOfWeek
676: * the Calendar day of the week on which daylight savings time
677: * starts
678: * @param time
679: * the time of day in milliseconds on which daylight savings time
680: * starts
681: */
682: public void setStartRule(int month, int day, int dayOfWeek, int time) {
683: startMonth = month;
684: startDay = day;
685: startDayOfWeek = dayOfWeek;
686: startTime = time;
687: setStartMode();
688: if (isSimple) {
689: ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(
690: month, day, dayOfWeek, time);
691: }
692: }
693:
694: /**
695: * Sets the rule which specifies the start of daylight savings time.
696: *
697: * @param month
698: * the Calendar month in which daylight savings time starts
699: * @param day
700: * the Calendar day of the month
701: * @param dayOfWeek
702: * the Calendar day of the week on which daylight savings time
703: * starts
704: * @param time
705: * the time of day in milliseconds on which daylight savings time
706: * starts
707: * @param after
708: * selects the day after or before the day of month
709: */
710: public void setStartRule(int month, int day, int dayOfWeek,
711: int time, boolean after) {
712: startMonth = month;
713: startDay = after ? day : -day;
714: startDayOfWeek = -dayOfWeek;
715: startTime = time;
716: setStartMode();
717: if (isSimple) {
718: ((com.ibm.icu.util.SimpleTimeZone) icuTZ).setStartRule(
719: month, day, dayOfWeek, time, after);
720: }
721: }
722:
723: /**
724: * Sets the starting year for daylight savings time in this SimpleTimeZone.
725: * Years before this start year will always be in standard time.
726: *
727: * @param year
728: * the starting year
729: */
730: public void setStartYear(int year) {
731: startYear = year;
732: useDaylight = true;
733: }
734:
735: /**
736: * Answers the string representation of this SimpleTimeZone.
737: *
738: * @return the string representation of this SimpleTimeZone
739: */
740: @Override
741: public String toString() {
742: return getClass().getName()
743: + "[id=" //$NON-NLS-1$
744: + getID()
745: + ",offset=" //$NON-NLS-1$
746: + rawOffset
747: + ",dstSavings=" //$NON-NLS-1$
748: + dstSavings
749: + ",useDaylight=" //$NON-NLS-1$
750: + useDaylight
751: + ",startYear=" //$NON-NLS-1$
752: + startYear
753: + ",startMode=" //$NON-NLS-1$
754: + startMode
755: + ",startMonth=" //$NON-NLS-1$
756: + startMonth
757: + ",startDay=" //$NON-NLS-1$
758: + startDay
759: + ",startDayOfWeek=" //$NON-NLS-1$
760: + (useDaylight && (startMode != DOM_MODE) ? startDayOfWeek + 1
761: : 0)
762: + ",startTime=" + startTime + ",endMode=" //$NON-NLS-1$ //$NON-NLS-2$
763: + endMode
764: + ",endMonth=" + endMonth + ",endDay=" + endDay //$NON-NLS-1$ //$NON-NLS-2$
765: + ",endDayOfWeek=" //$NON-NLS-1$
766: + (useDaylight && (endMode != DOM_MODE) ? endDayOfWeek + 1
767: : 0) + ",endTime=" + endTime + "]"; //$NON-NLS-1$//$NON-NLS-2$
768: }
769:
770: /**
771: * Answers if this TimeZone has a daylight savings time period.
772: *
773: * @return true if this time zone has a daylight savings time period, false
774: * otherwise
775: */
776: @Override
777: public boolean useDaylightTime() {
778: return useDaylight;
779: }
780:
781: private static final ObjectStreamField[] serialPersistentFields = {
782: new ObjectStreamField("dstSavings", Integer.TYPE), //$NON-NLS-1$
783: new ObjectStreamField("endDay", Integer.TYPE), //$NON-NLS-1$
784: new ObjectStreamField("endDayOfWeek", Integer.TYPE), //$NON-NLS-1$
785: new ObjectStreamField("endMode", Integer.TYPE), //$NON-NLS-1$
786: new ObjectStreamField("endMonth", Integer.TYPE), //$NON-NLS-1$
787: new ObjectStreamField("endTime", Integer.TYPE), //$NON-NLS-1$
788: new ObjectStreamField("monthLength", byte[].class), //$NON-NLS-1$
789: new ObjectStreamField("rawOffset", Integer.TYPE), //$NON-NLS-1$
790: new ObjectStreamField("serialVersionOnStream", Integer.TYPE), //$NON-NLS-1$
791: new ObjectStreamField("startDay", Integer.TYPE), //$NON-NLS-1$
792: new ObjectStreamField("startDayOfWeek", Integer.TYPE), //$NON-NLS-1$
793: new ObjectStreamField("startMode", Integer.TYPE), //$NON-NLS-1$
794: new ObjectStreamField("startMonth", Integer.TYPE), //$NON-NLS-1$
795: new ObjectStreamField("startTime", Integer.TYPE), //$NON-NLS-1$
796: new ObjectStreamField("startYear", Integer.TYPE), //$NON-NLS-1$
797: new ObjectStreamField("useDaylight", Boolean.TYPE), }; //$NON-NLS-1$
798:
799: private void writeObject(ObjectOutputStream stream)
800: throws IOException {
801: int sEndDay = endDay, sEndDayOfWeek = endDayOfWeek + 1, sStartDay = startDay, sStartDayOfWeek = startDayOfWeek + 1;
802: if (useDaylight
803: && (startMode != DOW_IN_MONTH_MODE || endMode != DOW_IN_MONTH_MODE)) {
804: Calendar cal = new GregorianCalendar(this );
805: if (endMode != DOW_IN_MONTH_MODE) {
806: cal.set(Calendar.MONTH, endMonth);
807: cal.set(Calendar.DATE, endDay);
808: sEndDay = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
809: if (endMode == DOM_MODE) {
810: sEndDayOfWeek = cal.getFirstDayOfWeek();
811: }
812: }
813: if (startMode != DOW_IN_MONTH_MODE) {
814: cal.set(Calendar.MONTH, startMonth);
815: cal.set(Calendar.DATE, startDay);
816: sStartDay = cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
817: if (startMode == DOM_MODE) {
818: sStartDayOfWeek = cal.getFirstDayOfWeek();
819: }
820: }
821: }
822: ObjectOutputStream.PutField fields = stream.putFields();
823: fields.put("dstSavings", dstSavings); //$NON-NLS-1$
824: fields.put("endDay", sEndDay); //$NON-NLS-1$
825: fields.put("endDayOfWeek", sEndDayOfWeek); //$NON-NLS-1$
826: fields.put("endMode", endMode); //$NON-NLS-1$
827: fields.put("endMonth", endMonth); //$NON-NLS-1$
828: fields.put("endTime", endTime); //$NON-NLS-1$
829: fields.put("monthLength", GregorianCalendar.DaysInMonth); //$NON-NLS-1$
830: fields.put("rawOffset", rawOffset); //$NON-NLS-1$
831: fields.put("serialVersionOnStream", 1); //$NON-NLS-1$
832: fields.put("startDay", sStartDay); //$NON-NLS-1$
833: fields.put("startDayOfWeek", sStartDayOfWeek); //$NON-NLS-1$
834: fields.put("startMode", startMode); //$NON-NLS-1$
835: fields.put("startMonth", startMonth); //$NON-NLS-1$
836: fields.put("startTime", startTime); //$NON-NLS-1$
837: fields.put("startYear", startYear); //$NON-NLS-1$
838: fields.put("useDaylight", useDaylight); //$NON-NLS-1$
839: stream.writeFields();
840: stream.writeInt(4);
841: byte[] values = new byte[4];
842: values[0] = (byte) startDay;
843: values[1] = (byte) (startMode == DOM_MODE ? 0
844: : startDayOfWeek + 1);
845: values[2] = (byte) endDay;
846: values[3] = (byte) (endMode == DOM_MODE ? 0 : endDayOfWeek + 1);
847: stream.write(values);
848: }
849:
850: private void readObject(ObjectInputStream stream)
851: throws IOException, ClassNotFoundException {
852: ObjectInputStream.GetField fields = stream.readFields();
853: rawOffset = fields.get("rawOffset", 0); //$NON-NLS-1$
854: useDaylight = fields.get("useDaylight", false); //$NON-NLS-1$
855: if (useDaylight) {
856: endMonth = fields.get("endMonth", 0); //$NON-NLS-1$
857: endTime = fields.get("endTime", 0); //$NON-NLS-1$
858: startMonth = fields.get("startMonth", 0); //$NON-NLS-1$
859: startTime = fields.get("startTime", 0); //$NON-NLS-1$
860: startYear = fields.get("startYear", 0); //$NON-NLS-1$
861: }
862: if (fields.get("serialVersionOnStream", 0) == 0) { //$NON-NLS-1$
863: if (useDaylight) {
864: startMode = endMode = DOW_IN_MONTH_MODE;
865: endDay = fields.get("endDay", 0); //$NON-NLS-1$
866: endDayOfWeek = fields.get("endDayOfWeek", 0) - 1; //$NON-NLS-1$
867: startDay = fields.get("startDay", 0); //$NON-NLS-1$
868: startDayOfWeek = fields.get("startDayOfWeek", 0) - 1; //$NON-NLS-1$
869: }
870: } else {
871: dstSavings = fields.get("dstSavings", 0); //$NON-NLS-1$
872: if (useDaylight) {
873: endMode = fields.get("endMode", 0); //$NON-NLS-1$
874: startMode = fields.get("startMode", 0); //$NON-NLS-1$
875: int length = stream.readInt();
876: byte[] values = new byte[length];
877: stream.readFully(values);
878: if (length >= 4) {
879: startDay = values[0];
880: startDayOfWeek = values[1];
881: if (startMode != DOM_MODE) {
882: startDayOfWeek--;
883: }
884: endDay = values[2];
885: endDayOfWeek = values[3];
886: if (endMode != DOM_MODE) {
887: endDayOfWeek--;
888: }
889: }
890: }
891: }
892: }
893:
894: }
|