001: /*
002: * @(#)Time.java 1.8 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.tools.javazic;
029:
030: import java.util.ArrayList;
031: import sun.util.calendar.CalendarDate;
032: import sun.util.calendar.Gregorian;
033:
034: /**
035: * Time class represents the "AT" field and other time related information.
036: *
037: * @since 1.4
038: */
039: class Time {
040:
041: // type is wall clock time
042: private static final int WALL = 1;
043:
044: // type is standard time
045: private static final int STD = 2;
046:
047: // type is UTC
048: private static final int UTC = 3;
049:
050: // type of representing time
051: private int type;
052:
053: /**
054: * Time from the EPOCH in milliseconds
055: */
056: private long time;
057:
058: /**
059: * Current time in milliseconds
060: */
061: private static long currentTime = System.currentTimeMillis();
062:
063: Time() {
064: time = 0L;
065: }
066:
067: Time(long time) {
068: this .time = time;
069: }
070:
071: void setType(int type) {
072: this .type = type;
073: }
074:
075: long getTime() {
076: return time;
077: }
078:
079: int getType() {
080: return type;
081: }
082:
083: static long getCurrentTime() {
084: return currentTime;
085: }
086:
087: /**
088: * @return true if the time is represented in wall-clock time.
089: */
090: boolean isWall() {
091: return type == WALL;
092: }
093:
094: /**
095: * @return true if the time is represented in standard time.
096: */
097: boolean isSTD() {
098: return type == STD;
099: }
100:
101: /**
102: * @return true if the time is represented in UTC time.
103: */
104: boolean isUTC() {
105: return type == UTC;
106: }
107:
108: /**
109: * Converts the type to a string that represents the type in the
110: * SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME").
111: * @return the converted string or null if the type is undefined.
112: */
113: String getTypeForSimpleTimeZone() {
114: String stz = "SimpleTimeZone.";
115: if (isWall()) {
116: return stz + "WALL_TIME";
117: } else if (isSTD()) {
118: return stz + "STANDARD_TIME";
119: } else if (isUTC()) {
120: return stz + "UTC_TIME";
121: } else {
122: return null;
123: }
124: }
125:
126: /**
127: * Converts the given Gregorian calendar field values to local time.
128: * Local time is represented by the amount of milliseconds from
129: * January 1, 1970 0:00 GMT.
130: * @param year the year value
131: * @param month the month value
132: * @param day the day represented by {@link RuleDay}
133: * @param save the amount of daylight time in milliseconds
134: * @param gmtOffset the GMT offset in milliseconds
135: * @param time the time of the day represented by {@link Time}
136: * @return local time
137: */
138: static long getLocalTime(int year, int month, RuleDay day,
139: int save, int gmtOffset, Time time) {
140: long t = time.getTime();
141:
142: if (time.isSTD())
143: t = time.getTime() + save;
144: else if (time.isUTC())
145: t = time.getTime() + save + gmtOffset;
146:
147: return getLocalTime(year, month, day, t);
148: }
149:
150: /**
151: * Converts the given Gregorian calendar field values to local time.
152: * Local time is represented by the amount of milliseconds from
153: * January 1, 1970 0:00 GMT.
154: * @param year the year value
155: * @param month the month value
156: * @param day the day value
157: * @param time the time of the day in milliseconds
158: * @return local time
159: */
160: static long getLocalTime(int year, int month, int day, long time) {
161: CalendarDate date = new CalendarDate(year, month, day);
162: long millis = Gregorian.dateToMillis(date);
163: return millis + time;
164: }
165:
166: /**
167: * Equivalent to <code>getLocalTime(year, month, day, (long)time)</code>.
168: * @param year the year value
169: * @param month the month value
170: * @param day the day value
171: * @param time the time of the day in milliseconds
172: * @return local time
173: */
174: static long getLocalTime(int year, int month, int day, int time) {
175: return getLocalTime(year, month, day, (long) time);
176: }
177:
178: /**
179: * Equivalent to {@link #getLocalTime(int, int, RuleDay, int)
180: * getLocalTime(year, month, day, (int) time)}.
181: * @param year the year value
182: * @param month the month value
183: * @param day the day represented by {@link RuleDay}
184: * @param time the time of the day represented by {@link Time}
185: * @return local time
186: */
187: static long getLocalTime(int year, int month, RuleDay day, long time) {
188: return getLocalTime(year, month, day, (int) time);
189: }
190:
191: /**
192: * Converts the given Gregorian calendar field values to local time.
193: * Local time is represented by the amount of milliseconds from
194: * January 1, 1970 0:00 GMT.
195: * @param year the year value
196: * @param month the month value
197: * @param day the day represented by {@link RuleDay}
198: * @param time the time of the day represented by {@link Time}
199: * @return local time
200: */
201: static long getLocalTime(int year, int month, RuleDay day, int time) {
202: long date = 0;
203: if (day.isLast()) { // e.g., "lastSun"
204: date = Calendar.getNthDayOfWeek(-1, day.getDayOfWeek(),
205: (int) Calendar.getFixedDate(year, month, Gregorian
206: .getMonthLength(year, month)));
207: } else if (day.isLater()) { // e.g., "Sun>=1"
208: date = Calendar.getNthDayOfWeek(1, day.getDayOfWeek(),
209: (int) Calendar.getFixedDate(year, month, day
210: .getDay()));
211: } else if (day.isExact()) {
212: date = Calendar.getFixedDate(year, month, day.getDay());
213: } else if (day.isEarlier()) { // e.g., "Sun<=15"
214: date = Calendar.getNthDayOfWeek(-1, day.getDayOfWeek(),
215: (int) Calendar.getFixedDate(year, month, day
216: .getDay()));
217: } else {
218: Main.panic("invalid day type: " + day);
219: }
220: return ((date - Calendar.EPOCH_DATE) * Calendar.ONE_DAY) + time;
221: }
222:
223: /**
224: * Parses the given "AT" field and constructs a Time object.
225: * @param the "AT" field string
226: * @return the Time object
227: */
228: static Time parse(String time) {
229: int sign;
230: int index = 0;
231: Time tm;
232:
233: if (time.charAt(0) == '-') {
234: sign = -1;
235: index++;
236: } else {
237: sign = 1;
238: }
239: int val = 0;
240: int num = 0;
241: int countDelim = 0;
242: while (index < time.length()) {
243: char c = time.charAt(index++);
244: if (c == ':') {
245: val = val * 60 + num;
246: countDelim++;
247: num = 0;
248: continue;
249: }
250: int d = Character.digit(c, 10);
251: if (d == -1) {
252: --index;
253: break;
254: }
255: num = num * 10 + d;
256: }
257: val = val * 60 + num;
258: // convert val to second
259: for (; countDelim < 2; countDelim++) {
260: val *= 60;
261: }
262: tm = new Time((long) val * 1000 * sign);
263: if (index < time.length()) {
264: char c = time.charAt(index++);
265: if (c == 's') {
266: tm.setType(tm.STD);
267: } else if (c == 'u' || c == 'g' || c == 'z') {
268: tm.setType(tm.UTC);
269: } else if (c == 'w') {
270: tm.setType(tm.WALL);
271: } else {
272: Main.panic("unknown time mode: " + c);
273: }
274: } else {
275: tm.setType(tm.WALL);
276: }
277: return tm;
278: }
279:
280: /**
281: * Converts the given milliseconds string to a "GMT[+-]hh:mm" string.
282: * @param ms the milliseconds string
283: */
284: static String toGMTFormat(String ms) {
285: long l = Long.parseLong(ms) / 1000;
286: String s;
287:
288: if (l < 0) {
289: s = "-";
290: l = -l;
291: } else {
292: s = "+";
293: }
294:
295: if (l < 36000) {
296: s += "0";
297: }
298:
299: /* Get hour */
300: s += l / 3600;
301: l %= 3600;
302:
303: s += ":";
304:
305: /* Get minute */
306: if (l < 600) {
307: s += "0";
308: }
309:
310: s += l / 60;
311:
312: return s;
313: }
314:
315: /**
316: * Converts the given millisecond value to a string for a
317: * SimpleTimeZone parameter.
318: * @param ms the millisecond value
319: * @return the string in a human readable form
320: */
321: static String toFormedString(int ms) {
322: StringBuffer s = new StringBuffer();
323: boolean minus = false;
324:
325: if (ms < 0) {
326: s.append("-");
327: minus = true;
328: ms = -ms;
329: } else if (ms == 0) {
330: return "0";
331: }
332:
333: int hour = ms / Calendar.ONE_HOUR;
334: ms %= Calendar.ONE_HOUR;
335: int minute = ms / Calendar.ONE_MINUTE;
336:
337: if (hour != 0) {
338: if (minus && minute != 0) {
339: s.append("(");
340: }
341: s.append(Integer.toString(hour) + "*ONE_HOUR");
342: }
343:
344: if (minute != 0) {
345: if (hour != 0) {
346: s.append("+");
347: }
348: s.append(Integer.toString(minute) + "*ONE_MINUTE");
349: if (minus && hour != 0) {
350: s.append(")");
351: }
352: }
353:
354: return s.toString();
355: }
356: }
|