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