15658
|
1 |
/*
|
|
2 |
* Copyright (c) 2000, 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
|
|
23 |
* questions.
|
|
24 |
*/
|
|
25 |
|
|
26 |
import java.util.Locale;
|
|
27 |
import sun.util.calendar.CalendarDate;
|
|
28 |
import sun.util.calendar.CalendarSystem;
|
|
29 |
import sun.util.calendar.Gregorian;
|
|
30 |
|
|
31 |
/**
|
|
32 |
* Time class represents the "AT" field and other time related information.
|
|
33 |
*
|
|
34 |
* @since 1.4
|
|
35 |
*/
|
|
36 |
class Time {
|
|
37 |
|
|
38 |
static final Gregorian gcal = CalendarSystem.getGregorianCalendar();
|
|
39 |
|
|
40 |
// type is wall clock time
|
|
41 |
private static final int WALL = 1;
|
|
42 |
|
|
43 |
// type is standard time
|
|
44 |
private static final int STD = 2;
|
|
45 |
|
|
46 |
// type is UTC
|
|
47 |
private static final int UTC = 3;
|
|
48 |
|
|
49 |
// type of representing time
|
|
50 |
private int type;
|
|
51 |
|
|
52 |
/**
|
|
53 |
* Time from the EPOCH in milliseconds
|
|
54 |
*/
|
|
55 |
private long time;
|
|
56 |
|
|
57 |
/**
|
|
58 |
* Current time in milliseconds
|
|
59 |
*/
|
|
60 |
private static final long currentTime = System.currentTimeMillis();
|
|
61 |
|
|
62 |
Time() {
|
|
63 |
time = 0L;
|
|
64 |
}
|
|
65 |
|
|
66 |
Time(long time) {
|
|
67 |
this.time = time;
|
|
68 |
}
|
|
69 |
|
|
70 |
void setType(int type) {
|
|
71 |
this.type = type;
|
|
72 |
}
|
|
73 |
|
|
74 |
long getTime() {
|
|
75 |
return time;
|
|
76 |
}
|
|
77 |
|
|
78 |
int getType() {
|
|
79 |
return type;
|
|
80 |
}
|
|
81 |
|
|
82 |
static long getCurrentTime() {
|
|
83 |
return currentTime;
|
|
84 |
}
|
|
85 |
|
|
86 |
/**
|
|
87 |
* @return true if the time is represented in wall-clock time.
|
|
88 |
*/
|
|
89 |
boolean isWall() {
|
|
90 |
return type == WALL;
|
|
91 |
}
|
|
92 |
|
|
93 |
/**
|
|
94 |
* @return true if the time is represented in standard time.
|
|
95 |
*/
|
|
96 |
boolean isSTD() {
|
|
97 |
return type == STD;
|
|
98 |
}
|
|
99 |
|
|
100 |
/**
|
|
101 |
* @return true if the time is represented in UTC time.
|
|
102 |
*/
|
|
103 |
boolean isUTC() {
|
|
104 |
return type == UTC;
|
|
105 |
}
|
|
106 |
|
|
107 |
/**
|
|
108 |
* Converts the type to a string that represents the type in the
|
|
109 |
* SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME").
|
|
110 |
* @return the converted string or null if the type is undefined.
|
|
111 |
*/
|
|
112 |
String getTypeForSimpleTimeZone() {
|
|
113 |
String stz = "SimpleTimeZone.";
|
|
114 |
if (isWall()) {
|
|
115 |
return stz+"WALL_TIME";
|
|
116 |
}
|
|
117 |
else if (isSTD()) {
|
|
118 |
return stz+"STANDARD_TIME";
|
|
119 |
}
|
|
120 |
else if (isUTC()) {
|
|
121 |
return stz+"UTC_TIME";
|
|
122 |
}
|
|
123 |
else {
|
|
124 |
return null;
|
|
125 |
}
|
|
126 |
}
|
|
127 |
|
|
128 |
/**
|
|
129 |
* Converts the given Gregorian calendar field values to local time.
|
|
130 |
* Local time is represented by the amount of milliseconds from
|
|
131 |
* January 1, 1970 0:00 GMT.
|
|
132 |
* @param year the year value
|
|
133 |
* @param month the Month value
|
|
134 |
* @param day the day represented by {@link RuleDay}
|
|
135 |
* @param save the amount of daylight time in milliseconds
|
|
136 |
* @param gmtOffset the GMT offset in milliseconds
|
|
137 |
* @param time the time of the day represented by {@link Time}
|
|
138 |
* @return local time
|
|
139 |
*/
|
|
140 |
static long getLocalTime(int year, Month month, RuleDay day, int save,
|
|
141 |
int gmtOffset, Time time) {
|
|
142 |
long t = time.getTime();
|
|
143 |
|
|
144 |
if (time.isSTD())
|
|
145 |
t = time.getTime() + save;
|
|
146 |
else if (time.isUTC())
|
|
147 |
t = time.getTime() + save + gmtOffset;
|
|
148 |
|
|
149 |
return getLocalTime(year, month, day, t);
|
|
150 |
}
|
|
151 |
|
|
152 |
/**
|
|
153 |
* Converts the given Gregorian calendar field values to local time.
|
|
154 |
* Local time is represented by the amount of milliseconds from
|
|
155 |
* January 1, 1970 0:00 GMT.
|
|
156 |
* @param year the year value
|
|
157 |
* @param month the Month value
|
|
158 |
* @param day the day value
|
|
159 |
* @param time the time of the day in milliseconds
|
|
160 |
* @return local time
|
|
161 |
*/
|
|
162 |
static long getLocalTime(int year, Month month, int day, long time) {
|
|
163 |
CalendarDate date = gcal.newCalendarDate(null);
|
|
164 |
date.setDate(year, month.value(), day);
|
|
165 |
long millis = gcal.getTime(date);
|
|
166 |
return millis + time;
|
|
167 |
}
|
|
168 |
|
|
169 |
/**
|
|
170 |
* Equivalent to <code>getLocalTime(year, month, day, (long)time)</code>.
|
|
171 |
* @param year the year value
|
|
172 |
* @param month the Month value
|
|
173 |
* @param day the day value
|
|
174 |
* @param time the time of the day in milliseconds
|
|
175 |
* @return local time
|
|
176 |
*/
|
|
177 |
static long getLocalTime(int year, Month month, int day, int time) {
|
|
178 |
return getLocalTime(year, month, day, (long)time);
|
|
179 |
}
|
|
180 |
|
|
181 |
/**
|
|
182 |
* Equivalent to {@link #getLocalTime(int, Month, RuleDay, int)
|
|
183 |
* getLocalTime(year, month, day, (int) time)}.
|
|
184 |
* @param year the year value
|
|
185 |
* @param month the Month value
|
|
186 |
* @param day the day represented by {@link RuleDay}
|
|
187 |
* @param time the time of the day represented by {@link Time}
|
|
188 |
* @return local time
|
|
189 |
*/
|
|
190 |
static long getLocalTime(int year, Month month, RuleDay day, 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, int time) {
|
|
205 |
CalendarDate cdate = gcal.newCalendarDate(null);
|
|
206 |
int monthValue = month.value();
|
|
207 |
|
|
208 |
if (day.isLast()) { // e.g., "lastSun"
|
|
209 |
cdate.setDate(year, monthValue, 1);
|
|
210 |
cdate.setDayOfMonth(gcal.getMonthLength(cdate));
|
|
211 |
cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
|
|
212 |
} else if (day.isLater()) { // e.g., "Sun>=1"
|
|
213 |
cdate.setDate(year, monthValue, day.getDay());
|
|
214 |
cdate = gcal.getNthDayOfWeek(1, day.getDayOfWeekNum(), cdate);
|
|
215 |
} else if (day.isExact()) {
|
|
216 |
cdate.setDate(year, monthValue, day.getDay());
|
|
217 |
} else if (day.isEarlier()) { // e.g., "Sun<=15"
|
|
218 |
cdate.setDate(year, monthValue, day.getDay());
|
|
219 |
cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
|
|
220 |
} else {
|
|
221 |
Main.panic("invalid day type: " + day);
|
|
222 |
}
|
|
223 |
return gcal.getTime(cdate) + time;
|
|
224 |
}
|
|
225 |
|
|
226 |
/**
|
|
227 |
* Parses the given "AT" field and constructs a Time object.
|
|
228 |
* @param the "AT" field string
|
|
229 |
* @return the Time object
|
|
230 |
*/
|
|
231 |
static Time parse(String time) {
|
|
232 |
int sign;
|
|
233 |
int index = 0;
|
|
234 |
Time tm;
|
|
235 |
|
|
236 |
if (time.charAt(0) == '-') {
|
|
237 |
sign = -1;
|
|
238 |
index++;
|
|
239 |
} else {
|
|
240 |
sign = 1;
|
|
241 |
}
|
|
242 |
int val = 0;
|
|
243 |
int num = 0;
|
|
244 |
int countDelim = 0;
|
|
245 |
while (index < time.length()) {
|
|
246 |
char c = time.charAt(index++);
|
|
247 |
if (c == ':') {
|
|
248 |
val = val * 60 + num;
|
|
249 |
countDelim++;
|
|
250 |
num = 0;
|
|
251 |
continue;
|
|
252 |
}
|
|
253 |
int d = Character.digit(c, 10);
|
|
254 |
if (d == -1) {
|
|
255 |
--index;
|
|
256 |
break;
|
|
257 |
}
|
|
258 |
num = num * 10 + d;
|
|
259 |
}
|
|
260 |
val = val * 60 + num;
|
|
261 |
// convert val to second
|
|
262 |
for (; countDelim < 2; countDelim++) {
|
|
263 |
val *= 60;
|
|
264 |
}
|
|
265 |
tm = new Time((long)val * 1000 * sign);
|
|
266 |
if (index < time.length()) {
|
|
267 |
char c = time.charAt(index++);
|
|
268 |
if (c == 's') {
|
|
269 |
tm.setType(Time.STD);
|
|
270 |
} else if (c == 'u' || c == 'g' || c == 'z') {
|
|
271 |
tm.setType(Time.UTC);
|
|
272 |
} else if (c == 'w') {
|
|
273 |
tm.setType(Time.WALL);
|
|
274 |
} else {
|
|
275 |
Main.panic("unknown time mode: "+c);
|
|
276 |
}
|
|
277 |
} else {
|
|
278 |
tm.setType(Time.WALL);
|
|
279 |
}
|
|
280 |
return tm;
|
|
281 |
}
|
|
282 |
|
|
283 |
/**
|
|
284 |
* Converts the given milliseconds string to a "[+-]hh:mm" string.
|
|
285 |
* @param ms the milliseconds string
|
|
286 |
*/
|
|
287 |
static String toGMTFormat(String ms) {
|
|
288 |
long sec = Long.parseLong(ms) / 1000;
|
|
289 |
char sign;
|
|
290 |
if (sec < 0) {
|
|
291 |
sign = '-';
|
|
292 |
sec = -sec;
|
|
293 |
} else {
|
|
294 |
sign = '+';
|
|
295 |
}
|
|
296 |
return String.format((Locale)null, "%c%02d:%02d",
|
|
297 |
sign, sec/3600, (sec%3600)/60);
|
|
298 |
}
|
|
299 |
|
|
300 |
/**
|
|
301 |
* Converts the given millisecond value to a string for a
|
|
302 |
* SimpleTimeZone parameter.
|
|
303 |
* @param ms the millisecond value
|
|
304 |
* @return the string in a human readable form
|
|
305 |
*/
|
|
306 |
static String toFormedString(int ms) {
|
|
307 |
StringBuilder s = new StringBuilder();
|
|
308 |
boolean minus = false;
|
|
309 |
|
|
310 |
if (ms < 0) {
|
|
311 |
s.append("-");
|
|
312 |
minus = true;
|
|
313 |
ms = -ms;
|
|
314 |
} else if (ms == 0) {
|
|
315 |
return "0";
|
|
316 |
}
|
|
317 |
|
|
318 |
int hour = ms / (60 * 60 * 1000);
|
|
319 |
ms %= (60 * 60 * 1000);
|
|
320 |
int minute = ms / (60 * 1000);
|
|
321 |
|
|
322 |
if (hour != 0) {
|
|
323 |
if (minus && minute != 0) {
|
|
324 |
s.append("(");
|
|
325 |
}
|
|
326 |
s.append(Integer.toString(hour) + "*ONE_HOUR");
|
|
327 |
}
|
|
328 |
|
|
329 |
if (minute != 0) {
|
|
330 |
if (hour != 0) {
|
|
331 |
s.append("+");
|
|
332 |
}
|
|
333 |
s.append(Integer.toString(minute) + "*ONE_MINUTE");
|
|
334 |
if (minus && hour != 0) {
|
|
335 |
s.append(")");
|
|
336 |
}
|
|
337 |
}
|
|
338 |
|
|
339 |
return s.toString();
|
|
340 |
}
|
|
341 |
}
|