📄 timezoneimpl.java
字号:
/* * Copyright (c) 1999 Sun Microsystems, Inc., 901 San Antonio Road, * Palo Alto, CA 94303, U.S.A. All Rights Reserved. * * Sun Microsystems, Inc. has intellectual property rights relating * to the technology embodied in this software. In particular, and * without limitation, these intellectual property rights may include * one or more U.S. patents, foreign patents, or pending * applications. Sun, Sun Microsystems, the Sun logo, Java, KJava, * and all Sun-based and Java-based marks are trademarks or * registered trademarks of Sun Microsystems, Inc. in the United * States and other countries. * * This software is distributed under licenses restricting its use, * copying, distribution, and decompilation. No part of this * software may be reproduced in any form by any means without prior * written authorization of Sun and its licensors, if any. * * FEDERAL ACQUISITIONS: Commercial Software -- Government Users * Subject to Standard License Terms and Conditions */package com.sun.cldc.util.j2me;import java.util.*;public class TimeZoneImpl extends TimeZone { static String HOME_ID = null; public TimeZoneImpl() {} /** * Constructs a TimeZone with the given base time zone offset from GMT * and time zone ID. Timezone IDs can be obtained from * TimeZone.getAvailableIDs. Normally you should use TimeZone.getDefault to * construct a TimeZone. * * @param rawOffset The given base time zone offset to GMT. * @param ID The time zone ID which is obtained from * TimeZone.getAvailableIDs. */ private TimeZoneImpl(int rawOffset, String ID) { this.rawOffset = rawOffset; this.ID = ID; dstSavings = millisPerHour; // In case user sets rules later } /** * Constructor. This constructor is identical to the 10-argument * constructor, but also takes a dstSavings parameter. * @param dstSavings The amount of time in ms saved during DST. * @exception IllegalArgumentException the month, day, dayOfWeek, or time * parameters are out of range for the start or end rule */ private TimeZoneImpl(int rawOffset, String ID, int startMonth, int startDay, int startDayOfWeek, int startTime, int endMonth, int endDay, int endDayOfWeek, int endTime, int dstSavings) { this.ID = ID; this.rawOffset = rawOffset; this.startMonth = startMonth; this.startDay = startDay; this.startDayOfWeek = startDayOfWeek; this.startTime = startTime; this.endMonth = endMonth; this.endDay = endDay; this.endDayOfWeek = endDayOfWeek; this.endTime = endTime; this.dstSavings = dstSavings; decodeRules(); if (dstSavings <= 0) { throw new IllegalArgumentException("Illegal DST savings"); } } // Constants used internally; unit is milliseconds private static final int ONE_MINUTE = 60*1000; private static final int ONE_HOUR = 60*ONE_MINUTE; private static final int ONE_DAY = 24*ONE_HOUR; /** * Gets offset, for current date, modified in case of * daylight savings. This is the offset to add *to* GMT to get local time. * Gets the time zone offset, for current date, modified in case of daylight * savings. This is the offset to add *to* GMT to get local time. Assume * that the start and end month are distinct. This method may return incorrect * results for rules that start at the end of February (e.g., last Sunday in * February) or the beginning of March (e.g., March 1). * * @param era The era of the given date (0 = BC, 1 = AD). * @param year The year in the given date. * @param month The month in the given date. Month is 0-based. e.g., * 0 for January. * @param day The day-in-month of the given date. * @param dayOfWeek The day-of-week of the given date. * @param millis The milliseconds in day in <em>standard</em> local time. * @return The offset to add *to* GMT to get local time. * @exception IllegalArgumentException the era, month, day, * dayOfWeek, or millis parameters are out of range */ public int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis) { if (month < Calendar.JANUARY || month > Calendar.DECEMBER) { throw new IllegalArgumentException("Illegal month " + month); } return getOffset(era, year, month, day, dayOfWeek, millis, staticMonthLength[month]); } /** * Gets offset, for current date, modified in case of * daylight savings. This is the offset to add <em>to</em> GMT to get local time. * Gets the time zone offset, for current date, modified in case of daylight * savings. This is the offset to add *to* GMT to get local time. Assume * that the start and end month are distinct. * @param era The era of the given date (0 = BC, 1 = AD). * @param year The year in the given date. * @param month The month in the given date. Month is 0-based. e.g., * 0 for January. * @param day The day-in-month of the given date. * @param dayOfWeek The day-of-week of the given date. * @param millis The milliseconds in day in <em>standard</em> local time. * @param monthLength The length of the given month in days. * @return The offset to add *to* GMT to get local time. * @exception IllegalArgumentException the era, month, day, * dayOfWeek, millis, or monthLength parameters are out of range */ int getOffset(int era, int year, int month, int day, int dayOfWeek, int millis, int monthLength) { if (true) { /* Use this parameter checking code for normal operation. Only one * of these two blocks should actually get compiled into the class * file. */ if ((era != 0 && era != 1) || month < Calendar.JANUARY || month > Calendar.DECEMBER || day < 1 || day > monthLength || dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY || millis < 0 || millis >= millisPerDay || monthLength < 28 || monthLength > 31) { throw new IllegalArgumentException(); } } else { /* This parameter checking code is better for debugging, but * overkill for normal operation. Only one of these two blocks * should actually get compiled into the class file. */ if (era != 0 && era != 1) { throw new IllegalArgumentException("Illegal era " + era); } if (month < Calendar.JANUARY || month > Calendar.DECEMBER) { throw new IllegalArgumentException("Illegal month " + month); } if (day < 1 || day > monthLength) { throw new IllegalArgumentException("Illegal day " + day); } if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY) { throw new IllegalArgumentException("Illegal day of week " + dayOfWeek); } if (millis < 0 || millis >= millisPerDay) { throw new IllegalArgumentException("Illegal millis " + millis); } if (monthLength < 28 || monthLength > 31) { throw new IllegalArgumentException("Illegal month length " + monthLength); } } int result = rawOffset; // Bail out if we are before the onset of daylight savings time if (!useDaylight || year < startYear || era != 1) return result; // Check for southern hemisphere. We assume that the start and end // month are different. boolean southern = (startMonth > endMonth); // Compare the date to the starting and ending rules.+1 = date>rule, -1 // = date<rule, 0 = date==rule. int startCompare = compareToRule(month, monthLength, day, dayOfWeek, millis, startMode, startMonth, startDayOfWeek, startDay, startTime); int endCompare = 0; /* We don't always have to compute endCompare. For many instances, * startCompare is enough to determine if we are in DST or not. In the * northern hemisphere, if we are before the start rule, we can't have * DST. In the southern hemisphere, if we are after the start rule, we * must have DST. This is reflected in the way the next if statement * (not the one immediately following) short circuits. */ if (southern != (startCompare >= 0)) { /* For the ending rule comparison, we add the dstSavings to the millis * passed in to convert them from standard to wall time. We then must * normalize the millis to the range 0..millisPerDay-1. */ millis += dstSavings; // Assume dstSavings > 0 while (millis >= millisPerDay) { millis -= millisPerDay; ++day; dayOfWeek = 1 + (dayOfWeek % 7); // Assume dayOfWeek is one-based if (day > monthLength) { day = 1; /* When incrementing the month, it is desirable to overflow * from DECEMBER to DECEMBER+1, since we use the result to * compare against a real month. Wraparound of the value * leads to bug 4173604. */ ++month; } } endCompare = compareToRule(month, monthLength, day, dayOfWeek, millis, endMode, endMonth, endDayOfWeek, endDay, endTime); } // Check for both the northern and southern hemisphere cases. We // assume that in the northern hemisphere, the start rule is before the // end rule within the calendar year, and vice versa for the southern // hemisphere. if ((!southern && (startCompare >= 0 && endCompare < 0)) || (southern && (startCompare >= 0 || endCompare < 0))) result += dstSavings; return result; } /** * Compare a given date in the year to a rule. Return 1, 0, or -1, depending * on whether the date is after, equal to, or before the rule date. The * millis are compared directly against the ruleMillis, so any * standard-daylight adjustments must be handled by the caller. * * @return 1 if the date is after the rule date, -1 if the date is before * the rule date, or 0 if the date is equal to the rule date. */ private static int compareToRule(int month, int monthLen, int dayOfMonth, int dayOfWeek, int millis, int ruleMode, int ruleMonth, int ruleDayOfWeek, int ruleDay, int ruleMillis) { if (month < ruleMonth) return -1; else if (month > ruleMonth) return 1; int ruleDayOfMonth = 0; switch (ruleMode) { case DOM_MODE: ruleDayOfMonth = ruleDay; break; case DOW_IN_MONTH_MODE: // In this case ruleDay is the day-of-week-in-month if (ruleDay > 0) ruleDayOfMonth = 1 + (ruleDay - 1) * 7 + (7 + ruleDayOfWeek - (dayOfWeek - dayOfMonth + 1)) % 7; else // Assume ruleDay < 0 here { ruleDayOfMonth = monthLen + (ruleDay + 1) * 7 - (7 + (dayOfWeek + monthLen - dayOfMonth) - ruleDayOfWeek) % 7; } break; case DOW_GE_DOM_MODE: ruleDayOfMonth = ruleDay + (49 + ruleDayOfWeek - ruleDay - dayOfWeek + dayOfMonth) % 7; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -