1 /*
2 * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
24 */
25
26 /*
27 * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - All Rights Reserved
29 *
30 * The original version of this source code and documentation is copyrighted
31 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
32 * materials are provided under terms of a License Agreement between Taligent
33 * and Sun. This technology is protected by multiple US and International
34 * patents. This notice and attribution to Taligent may not be removed.
35 * Taligent is a registered trademark of Taligent, Inc.
36 *
37 */
38
39 package java.util;
40
41 import java.io.ObjectInputStream;
42 import java.io.ObjectOutputStream;
43 import java.io.IOException;
44 import sun.util.calendar.CalendarSystem;
45 import sun.util.calendar.CalendarUtils;
46 import sun.util.calendar.BaseCalendar;
47 import sun.util.calendar.Gregorian;
48
49 /**
50 * <code>SimpleTimeZone</code> is a concrete subclass of <code>TimeZone</code>
51 * that represents a time zone for use with a Gregorian calendar.
52 * The class holds an offset from GMT, called <em>raw offset</em>, and start
53 * and end rules for a daylight saving time schedule. Since it only holds
54 * single values for each, it cannot handle historical changes in the offset
55 * from GMT and the daylight saving schedule, except that the {@link
56 * #setStartYear setStartYear} method can specify the year when the daylight
57 * saving time schedule starts in effect.
58 * <p>
59 * To construct a <code>SimpleTimeZone</code> with a daylight saving time
60 * schedule, the schedule can be described with a set of rules,
61 * <em>start-rule</em> and <em>end-rule</em>. A day when daylight saving time
62 * starts or ends is specified by a combination of <em>month</em>,
63 * <em>day-of-month</em>, and <em>day-of-week</em> values. The <em>month</em>
1261 * </dd>
1262 * <dt><b>1</b></dt>
1263 * <dd>
1264 * JDK 1.1.4 or later. Includes three new fields: <code>startMode</code>,
1265 * <code>endMode</code>, and <code>dstSavings</code>.
1266 * </dd>
1267 * <dt><b>2</b></dt>
1268 * <dd>
1269 * JDK 1.3 or later. Includes two new fields: <code>startTimeMode</code>
1270 * and <code>endTimeMode</code>.
1271 * </dd>
1272 * </dl>
1273 * When streaming out this class, the most recent format
1274 * and the highest allowable <code>serialVersionOnStream</code>
1275 * is written.
1276 * @serial
1277 * @since 1.1.4
1278 */
1279 private int serialVersionOnStream = currentSerialVersion;
1280
1281 synchronized private void invalidateCache() {
1282 cacheYear = startYear - 1;
1283 cacheStart = cacheEnd = 0;
1284 }
1285
1286 //----------------------------------------------------------------------
1287 // Rule representation
1288 //
1289 // We represent the following flavors of rules:
1290 // 5 the fifth of the month
1291 // lastSun the last Sunday in the month
1292 // lastMon the last Monday in the month
1293 // Sun>=8 first Sunday on or after the eighth
1294 // Sun<=25 last Sunday on or before the 25th
1295 // This is further complicated by the fact that we need to remain
1296 // backward compatible with the 1.1 FCS. Finally, we need to minimize
1297 // API changes. In order to satisfy these requirements, we support
1298 // three representation systems, and we translate between them.
1299 //
1300 // INTERNAL REPRESENTATION
1552 break;
1553 case STANDARD_TIME:
1554 endTime += dstSavings;
1555 }
1556 while (endTime < 0) {
1557 endTime += millisPerDay;
1558 endDayOfWeek = 1 + ((endDayOfWeek+5) % 7); // Back 1 day
1559 }
1560 while (endTime >= millisPerDay) {
1561 endTime -= millisPerDay;
1562 endDayOfWeek = 1 + (endDayOfWeek % 7); // Forward 1 day
1563 }
1564 }
1565
1566 /**
1567 * Pack the start and end rules into an array of bytes. Only pack
1568 * data which is not preserved by makeRulesCompatible.
1569 */
1570 private byte[] packRules()
1571 {
1572 byte[] rules = new byte[6];
1573 rules[0] = (byte)startDay;
1574 rules[1] = (byte)startDayOfWeek;
1575 rules[2] = (byte)endDay;
1576 rules[3] = (byte)endDayOfWeek;
1577
1578 // As of serial version 2, include time modes
1579 rules[4] = (byte)startTimeMode;
1580 rules[5] = (byte)endTimeMode;
1581
1582 return rules;
1583 }
1584
1585 /**
1586 * Given an array of bytes produced by packRules, interpret them
1587 * as the start and end rules.
1588 */
1589 private void unpackRules(byte[] rules)
1590 {
1591 startDay = rules[0];
1592 startDayOfWeek = rules[1];
1593 endDay = rules[2];
1594 endDayOfWeek = rules[3];
1595
1596 // As of serial version 2, include time modes
1597 if (rules.length >= 6) {
1598 startTimeMode = rules[4];
1599 endTimeMode = rules[5];
1600 }
1601 }
1602
1603 /**
1604 * Pack the start and end times into an array of bytes. This is required
1605 * as of serial version 2.
1606 */
1607 private int[] packTimes() {
1608 int[] times = new int[2];
1609 times[0] = startTime;
1610 times[1] = endTime;
1611 return times;
1612 }
1613
1614 /**
1615 * Unpack the start and end times from an array of bytes. This is required
1616 * as of serial version 2.
1617 */
1674 if (serialVersionOnStream < 1) {
1675 // Fix a bug in the 1.1 SimpleTimeZone code -- namely,
1676 // startDayOfWeek and endDayOfWeek were usually uninitialized. We can't do
1677 // too much, so we assume SUNDAY, which actually works most of the time.
1678 if (startDayOfWeek == 0) {
1679 startDayOfWeek = Calendar.SUNDAY;
1680 }
1681 if (endDayOfWeek == 0) {
1682 endDayOfWeek = Calendar.SUNDAY;
1683 }
1684
1685 // The variables dstSavings, startMode, and endMode are post-1.1, so they
1686 // won't be present if we're reading from a 1.1 stream. Fix them up.
1687 startMode = endMode = DOW_IN_MONTH_MODE;
1688 dstSavings = millisPerHour;
1689 } else {
1690 // For 1.1.4, in addition to the 3 new instance variables, we also
1691 // store the actual rules (which have not be made compatible with 1.1)
1692 // in the optional area. Read them in here and parse them.
1693 int length = stream.readInt();
1694 byte[] rules = new byte[length];
1695 stream.readFully(rules);
1696 unpackRules(rules);
1697 }
1698
1699 if (serialVersionOnStream >= 2) {
1700 int[] times = (int[]) stream.readObject();
1701 unpackTimes(times);
1702 }
1703
1704 serialVersionOnStream = currentSerialVersion;
1705 }
1706 }
|
1 /*
2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
24 */
25
26 /*
27 * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
28 * (C) Copyright IBM Corp. 1996 - All Rights Reserved
29 *
30 * The original version of this source code and documentation is copyrighted
31 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
32 * materials are provided under terms of a License Agreement between Taligent
33 * and Sun. This technology is protected by multiple US and International
34 * patents. This notice and attribution to Taligent may not be removed.
35 * Taligent is a registered trademark of Taligent, Inc.
36 *
37 */
38
39 package java.util;
40
41 import java.io.ObjectInputStream;
42 import java.io.ObjectOutputStream;
43 import java.io.IOException;
44 import java.io.InvalidObjectException;
45 import sun.util.calendar.CalendarSystem;
46 import sun.util.calendar.CalendarUtils;
47 import sun.util.calendar.BaseCalendar;
48 import sun.util.calendar.Gregorian;
49
50 /**
51 * <code>SimpleTimeZone</code> is a concrete subclass of <code>TimeZone</code>
52 * that represents a time zone for use with a Gregorian calendar.
53 * The class holds an offset from GMT, called <em>raw offset</em>, and start
54 * and end rules for a daylight saving time schedule. Since it only holds
55 * single values for each, it cannot handle historical changes in the offset
56 * from GMT and the daylight saving schedule, except that the {@link
57 * #setStartYear setStartYear} method can specify the year when the daylight
58 * saving time schedule starts in effect.
59 * <p>
60 * To construct a <code>SimpleTimeZone</code> with a daylight saving time
61 * schedule, the schedule can be described with a set of rules,
62 * <em>start-rule</em> and <em>end-rule</em>. A day when daylight saving time
63 * starts or ends is specified by a combination of <em>month</em>,
64 * <em>day-of-month</em>, and <em>day-of-week</em> values. The <em>month</em>
1262 * </dd>
1263 * <dt><b>1</b></dt>
1264 * <dd>
1265 * JDK 1.1.4 or later. Includes three new fields: <code>startMode</code>,
1266 * <code>endMode</code>, and <code>dstSavings</code>.
1267 * </dd>
1268 * <dt><b>2</b></dt>
1269 * <dd>
1270 * JDK 1.3 or later. Includes two new fields: <code>startTimeMode</code>
1271 * and <code>endTimeMode</code>.
1272 * </dd>
1273 * </dl>
1274 * When streaming out this class, the most recent format
1275 * and the highest allowable <code>serialVersionOnStream</code>
1276 * is written.
1277 * @serial
1278 * @since 1.1.4
1279 */
1280 private int serialVersionOnStream = currentSerialVersion;
1281
1282 // Maximum number of rules.
1283 private static final int MAX_RULE_NUM = 6;
1284
1285 synchronized private void invalidateCache() {
1286 cacheYear = startYear - 1;
1287 cacheStart = cacheEnd = 0;
1288 }
1289
1290 //----------------------------------------------------------------------
1291 // Rule representation
1292 //
1293 // We represent the following flavors of rules:
1294 // 5 the fifth of the month
1295 // lastSun the last Sunday in the month
1296 // lastMon the last Monday in the month
1297 // Sun>=8 first Sunday on or after the eighth
1298 // Sun<=25 last Sunday on or before the 25th
1299 // This is further complicated by the fact that we need to remain
1300 // backward compatible with the 1.1 FCS. Finally, we need to minimize
1301 // API changes. In order to satisfy these requirements, we support
1302 // three representation systems, and we translate between them.
1303 //
1304 // INTERNAL REPRESENTATION
1556 break;
1557 case STANDARD_TIME:
1558 endTime += dstSavings;
1559 }
1560 while (endTime < 0) {
1561 endTime += millisPerDay;
1562 endDayOfWeek = 1 + ((endDayOfWeek+5) % 7); // Back 1 day
1563 }
1564 while (endTime >= millisPerDay) {
1565 endTime -= millisPerDay;
1566 endDayOfWeek = 1 + (endDayOfWeek % 7); // Forward 1 day
1567 }
1568 }
1569
1570 /**
1571 * Pack the start and end rules into an array of bytes. Only pack
1572 * data which is not preserved by makeRulesCompatible.
1573 */
1574 private byte[] packRules()
1575 {
1576 byte[] rules = new byte[MAX_RULE_NUM];
1577 rules[0] = (byte)startDay;
1578 rules[1] = (byte)startDayOfWeek;
1579 rules[2] = (byte)endDay;
1580 rules[3] = (byte)endDayOfWeek;
1581
1582 // As of serial version 2, include time modes
1583 rules[4] = (byte)startTimeMode;
1584 rules[5] = (byte)endTimeMode;
1585
1586 return rules;
1587 }
1588
1589 /**
1590 * Given an array of bytes produced by packRules, interpret them
1591 * as the start and end rules.
1592 */
1593 private void unpackRules(byte[] rules)
1594 {
1595 startDay = rules[0];
1596 startDayOfWeek = rules[1];
1597 endDay = rules[2];
1598 endDayOfWeek = rules[3];
1599
1600 // As of serial version 2, include time modes
1601 if (rules.length >= MAX_RULE_NUM) {
1602 startTimeMode = rules[4];
1603 endTimeMode = rules[5];
1604 }
1605 }
1606
1607 /**
1608 * Pack the start and end times into an array of bytes. This is required
1609 * as of serial version 2.
1610 */
1611 private int[] packTimes() {
1612 int[] times = new int[2];
1613 times[0] = startTime;
1614 times[1] = endTime;
1615 return times;
1616 }
1617
1618 /**
1619 * Unpack the start and end times from an array of bytes. This is required
1620 * as of serial version 2.
1621 */
1678 if (serialVersionOnStream < 1) {
1679 // Fix a bug in the 1.1 SimpleTimeZone code -- namely,
1680 // startDayOfWeek and endDayOfWeek were usually uninitialized. We can't do
1681 // too much, so we assume SUNDAY, which actually works most of the time.
1682 if (startDayOfWeek == 0) {
1683 startDayOfWeek = Calendar.SUNDAY;
1684 }
1685 if (endDayOfWeek == 0) {
1686 endDayOfWeek = Calendar.SUNDAY;
1687 }
1688
1689 // The variables dstSavings, startMode, and endMode are post-1.1, so they
1690 // won't be present if we're reading from a 1.1 stream. Fix them up.
1691 startMode = endMode = DOW_IN_MONTH_MODE;
1692 dstSavings = millisPerHour;
1693 } else {
1694 // For 1.1.4, in addition to the 3 new instance variables, we also
1695 // store the actual rules (which have not be made compatible with 1.1)
1696 // in the optional area. Read them in here and parse them.
1697 int length = stream.readInt();
1698 if (length <= MAX_RULE_NUM) {
1699 byte[] rules = new byte[length];
1700 stream.readFully(rules);
1701 unpackRules(rules);
1702 } else {
1703 throw new InvalidObjectException("Too many rules: " + length);
1704 }
1705 }
1706
1707 if (serialVersionOnStream >= 2) {
1708 int[] times = (int[]) stream.readObject();
1709 unpackTimes(times);
1710 }
1711
1712 serialVersionOnStream = currentSerialVersion;
1713 }
1714 }
|