|
1 /* |
|
2 * Copyright (c) 2000, 2004, 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.io.BufferedReader; |
|
27 import java.io.FileReader; |
|
28 import java.io.FileNotFoundException; |
|
29 import java.io.IOException; |
|
30 import java.util.ArrayList; |
|
31 import java.util.HashMap; |
|
32 import java.util.HashSet; |
|
33 import java.util.List; |
|
34 import java.util.Map; |
|
35 import java.util.Set; |
|
36 import java.util.StringTokenizer; |
|
37 |
|
38 /** |
|
39 * ZoneRec hold information of time zone corresponding to each text |
|
40 * line of the "Zone" part. |
|
41 * |
|
42 * @since 1.4 |
|
43 */ |
|
44 class ZoneRec { |
|
45 private int gmtOffset; |
|
46 private String ruleName; |
|
47 private int directSave; |
|
48 private Rule ruleRef; |
|
49 private String format; |
|
50 private boolean hasUntil; |
|
51 private int untilYear; |
|
52 private Month untilMonth; |
|
53 private RuleDay untilDay; |
|
54 private Time untilTime; |
|
55 private long untilInMillis; |
|
56 private String line; |
|
57 |
|
58 /** |
|
59 * @return the "UNTIL" value in milliseconds |
|
60 */ |
|
61 Time getUntilTime() { |
|
62 return untilTime; |
|
63 } |
|
64 |
|
65 /** |
|
66 * @return the GMT offset value in milliseconds |
|
67 */ |
|
68 int getGmtOffset() { |
|
69 return gmtOffset; |
|
70 } |
|
71 |
|
72 /** |
|
73 * @return the rule name to which this zone record refers |
|
74 */ |
|
75 String getRuleName() { |
|
76 return ruleName; |
|
77 } |
|
78 |
|
79 /** |
|
80 * @return the amount of saving time directly defined in the |
|
81 * "RULES/SAVE" field. |
|
82 */ |
|
83 int getDirectSave() { |
|
84 return directSave; |
|
85 } |
|
86 |
|
87 /** |
|
88 * @return true if this zone record has a reference to a rule |
|
89 */ |
|
90 boolean hasRuleReference() { |
|
91 return ruleRef != null; |
|
92 } |
|
93 |
|
94 /** |
|
95 * Returns the "FORMAT" field string of this zone record. This |
|
96 * @return the "FORMAT" field |
|
97 */ |
|
98 String getFormat() { |
|
99 return format; |
|
100 } |
|
101 |
|
102 /** |
|
103 * @return the year in the "UNTIL" field |
|
104 */ |
|
105 int getUntilYear() { |
|
106 return untilYear; |
|
107 } |
|
108 |
|
109 /** |
|
110 * Returns the "UNTIL" field value in milliseconds from Janurary |
|
111 * 1, 1970 0:00 GMT. |
|
112 * @param currentSave the amount of daylight saving in |
|
113 * milliseconds that is used to adjust wall-clock time. |
|
114 * @return the milliseconds value of the "UNTIL" field |
|
115 */ |
|
116 long getUntilTime(int currentSave) { |
|
117 if (untilTime.isWall()) { |
|
118 return untilInMillis - currentSave; |
|
119 } |
|
120 return untilInMillis; |
|
121 } |
|
122 |
|
123 /** |
|
124 * Returns the "UNTIL" time in milliseconds without adjusting GMT |
|
125 * offsets or daylight saving. |
|
126 * @return local "UNTIL" time in milliseconds |
|
127 */ |
|
128 long getLocalUntilTime() { |
|
129 return Time.getLocalTime(untilYear, |
|
130 untilMonth, |
|
131 untilDay, |
|
132 untilTime.getTime()); |
|
133 } |
|
134 |
|
135 /** |
|
136 * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving. |
|
137 * @return the "UNTIL" time after the adjustment |
|
138 */ |
|
139 long getLocalUntilTime(int save, int gmtOffset) { |
|
140 return Time.getLocalTime(untilYear, |
|
141 untilMonth, |
|
142 untilDay, |
|
143 save, |
|
144 gmtOffset, |
|
145 untilTime); |
|
146 } |
|
147 |
|
148 /** |
|
149 * @return the text line of this zone record |
|
150 */ |
|
151 String getLine() { |
|
152 return line; |
|
153 } |
|
154 |
|
155 /** |
|
156 * Sets the specified text line to this zone record |
|
157 */ |
|
158 void setLine(String line) { |
|
159 this.line = line; |
|
160 } |
|
161 |
|
162 /** |
|
163 * @return true if this zone record has the "UNTIL" field |
|
164 */ |
|
165 boolean hasUntil() { |
|
166 return this.hasUntil; |
|
167 } |
|
168 |
|
169 /** |
|
170 * Adjusts the "UNTIL" time to GMT offset if this zone record has |
|
171 * it. <code>untilTime</code> is not adjusted to daylight saving |
|
172 * in this method. |
|
173 */ |
|
174 void adjustTime() { |
|
175 if (!hasUntil()) { |
|
176 return; |
|
177 } |
|
178 if (untilTime.isSTD() || untilTime.isWall()) { |
|
179 // adjust to gmt offset only here. adjust to real |
|
180 // wall-clock time when tracking rules |
|
181 untilInMillis -= gmtOffset; |
|
182 } |
|
183 } |
|
184 |
|
185 /** |
|
186 * @return the reference to the Rule object |
|
187 */ |
|
188 Rule getRuleRef() { |
|
189 return ruleRef; |
|
190 } |
|
191 |
|
192 /** |
|
193 * Resolves the reference to a Rule and adjusts its "UNTIL" time |
|
194 * to GMT offset. |
|
195 */ |
|
196 void resolve(Zoneinfo zi) { |
|
197 if (ruleName != null && (!"-".equals(ruleName))) { |
|
198 ruleRef = zi.getRule(ruleName); |
|
199 } |
|
200 adjustTime(); |
|
201 } |
|
202 |
|
203 /** |
|
204 * Parses a Zone text line that is described by a StringTokenizer. |
|
205 * @param tokens represents tokens of a Zone text line |
|
206 * @return the zone record produced by parsing the text |
|
207 */ |
|
208 static ZoneRec parse(StringTokenizer tokens) { |
|
209 ZoneRec rec = new ZoneRec(); |
|
210 try { |
|
211 rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime(); |
|
212 String token = tokens.nextToken(); |
|
213 char c = token.charAt(0); |
|
214 if (c >= '0' && c <= '9') { |
|
215 rec.directSave = (int) Time.parse(token).getTime(); |
|
216 } else { |
|
217 rec.ruleName = token; |
|
218 } |
|
219 rec.format = tokens.nextToken(); |
|
220 if (tokens.hasMoreTokens()) { |
|
221 rec.hasUntil = true; |
|
222 rec.untilYear = Integer.parseInt(tokens.nextToken()); |
|
223 if (tokens.hasMoreTokens()) { |
|
224 rec.untilMonth = Month.parse(tokens.nextToken()); |
|
225 } else { |
|
226 rec.untilMonth = Month.JANUARY; |
|
227 } |
|
228 if (tokens.hasMoreTokens()) { |
|
229 rec.untilDay = RuleDay.parse(tokens.nextToken()); |
|
230 } else { |
|
231 rec.untilDay = new RuleDay(1); |
|
232 } |
|
233 if (tokens.hasMoreTokens()) { |
|
234 rec.untilTime = Time.parse(tokens.nextToken()); |
|
235 } else { |
|
236 rec.untilTime = Time.parse("0:00"); |
|
237 } |
|
238 rec.untilInMillis = rec.getLocalUntilTime(); |
|
239 } |
|
240 } catch (Exception e) { |
|
241 // TODO: error reporting |
|
242 e.printStackTrace(); |
|
243 } |
|
244 return rec; |
|
245 } |
|
246 |
|
247 private static void panic(String msg) { |
|
248 Main.panic(msg); |
|
249 } |
|
250 } |