]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/tools/misc/src/com/ibm/icu/dev/tool/timezone/ICUZDump.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / tools / misc / src / com / ibm / icu / dev / tool / timezone / ICUZDump.java
1 /*\r
2  ***********************************************************************\r
3  * Copyright (C) 2007, International Business Machines                 *\r
4  * Corporation and others. All Rights Reserved.                        *\r
5  ***********************************************************************\r
6  *\r
7  */\r
8 \r
9 package com.ibm.icu.dev.tool.timezone;\r
10 \r
11 import java.io.BufferedWriter;\r
12 import java.io.File;\r
13 import java.io.FileOutputStream;\r
14 import java.io.IOException;\r
15 import java.io.OutputStreamWriter;\r
16 import java.io.PrintWriter;\r
17 import java.io.Writer;\r
18 import java.lang.reflect.Method;\r
19 import java.util.ArrayList;\r
20 import java.util.Date;\r
21 import java.util.Iterator;\r
22 import java.util.List;\r
23 import java.util.TreeSet;\r
24 \r
25 import com.ibm.icu.text.DecimalFormat;\r
26 import com.ibm.icu.text.DecimalFormatSymbols;\r
27 import com.ibm.icu.text.SimpleDateFormat;\r
28 import com.ibm.icu.util.GregorianCalendar;\r
29 import com.ibm.icu.util.SimpleTimeZone;\r
30 import com.ibm.icu.util.ULocale;\r
31 \r
32 /**\r
33  * TimeZone transition dump tool.\r
34  */\r
35 public class ICUZDump {\r
36     private static final String DEFAULT_LINE_SEP;\r
37 \r
38     static {\r
39         String sep = System.getProperty("line.separator");\r
40         DEFAULT_LINE_SEP = (sep == null) ? "\n" : sep;\r
41     }\r
42 \r
43     private TimeZoneImpl tz = null;\r
44 \r
45     private int loyear = 1900;\r
46     private int hiyear = 2050;\r
47     private long tick = 1000;\r
48     private DumpFormatter formatter;\r
49     private String linesep = DEFAULT_LINE_SEP;\r
50 \r
51     public ICUZDump() {\r
52     }\r
53     \r
54     public void setLowYear(int loyear) {\r
55         this.loyear = loyear;\r
56     }\r
57     \r
58     public void setHighYear(int hiyear) {\r
59         this.hiyear = hiyear;\r
60     }\r
61 \r
62     public void setTick(int tick) {\r
63         if (tick <= 0) {\r
64             throw new IllegalArgumentException("tick must be positive");\r
65         }\r
66         this.tick = tick;\r
67     }\r
68     \r
69     public void setTimeZone(Object tzimpl) {\r
70         this.tz = new TimeZoneImpl(tzimpl);\r
71     }\r
72 \r
73     public void setDumpFormatter(DumpFormatter formatter) {\r
74         this.formatter = formatter;\r
75     }\r
76     \r
77     public void setLineSeparator(String sep) {\r
78         this.linesep = sep;\r
79     }\r
80     \r
81     public void dump(Writer w) throws IOException {\r
82         if (tz == null) {\r
83             throw new IllegalStateException("timezone is not initialized");\r
84         }\r
85 \r
86         if (formatter == null) {\r
87             formatter = new DumpFormatter();\r
88         }\r
89         \r
90         final long SEARCH_INCREMENT = 12 * 60 * 60 * 1000; // half day\r
91         long cutovers[] = getCutOverTimes();\r
92         long t = cutovers[0];\r
93         int offset = tz.getOffset(t);\r
94         boolean inDst = tz.inDaylightTime(t);\r
95         while (t < cutovers[1]) {\r
96             long newt = t + SEARCH_INCREMENT;\r
97             int newOffset = tz.getOffset(newt);\r
98             boolean newInDst = tz.inDaylightTime(newt);\r
99             if (offset != newOffset || inDst != newInDst) {\r
100                 // find the boundary\r
101                 long lot = t;\r
102                 long hit = newt;\r
103                 while (true) {\r
104                     long diff = hit - lot;\r
105                     if (diff <= tick) {\r
106                         break;\r
107                     }\r
108                     long medt = lot + ((diff / 2) / tick) * tick;\r
109                     int medOffset = tz.getOffset(medt);\r
110                     boolean medInDst = tz.inDaylightTime(medt);\r
111                     if (medOffset != offset || medInDst != inDst) {\r
112                         hit = medt;\r
113                     } else {\r
114                         lot = medt;\r
115                     }\r
116                 }\r
117                 w.write(formatter.format(lot, offset, tz.inDaylightTime(lot)));\r
118                 w.write(" > ");\r
119                 w.write(formatter.format(hit, newOffset, tz.inDaylightTime(hit)));\r
120                 w.write(linesep);\r
121                 offset = newOffset;\r
122                 inDst = newInDst;\r
123             }\r
124             t = newt;\r
125         }\r
126 \r
127     }\r
128     \r
129     private long[] getCutOverTimes() {\r
130         long[] cutovers = new long[2];\r
131         cutovers[0] = tz.getTime(loyear, 0, 1, 0, 0, 0);\r
132         cutovers[1] = tz.getTime(hiyear, 0, 1, 0, 0, 0);\r
133         return cutovers;\r
134     }\r
135 \r
136     private class TimeZoneImpl {\r
137         private Object tzobj;\r
138         \r
139         public TimeZoneImpl(Object tzobj) {\r
140             this.tzobj = tzobj;\r
141         }\r
142 \r
143         public int getOffset(long time) {\r
144             try {\r
145                 Method method = tzobj.getClass().getMethod("getOffset", new Class[] {long.class});\r
146                 Object result = method.invoke(tzobj, new Object[] {new Long(time)});\r
147                 return ((Integer)result).intValue();\r
148             } catch (Exception e) {\r
149                 e.printStackTrace();\r
150             }\r
151             return 0;\r
152         }\r
153 \r
154         public boolean inDaylightTime(long time) {\r
155             try {\r
156                 Method method = tzobj.getClass().getMethod("inDaylightTime", new Class[] {Date.class});\r
157                 Object result = method.invoke(tzobj, new Object[] {new Date(time)});\r
158                 return ((Boolean)result).booleanValue();\r
159             } catch (Exception e) {\r
160                 e.printStackTrace();\r
161             }\r
162             return false;\r
163         }\r
164 \r
165         public long getTime(int year, int month, int dayOfMonth, int hour, int minute, int second) {\r
166             long time;\r
167             if (tzobj instanceof com.ibm.icu.util.TimeZone) {\r
168                 GregorianCalendar cal = new GregorianCalendar();\r
169                 cal.setTimeZone((com.ibm.icu.util.TimeZone)tzobj);\r
170                 cal.clear();\r
171                 cal.set(year, month, dayOfMonth, hour, minute, second);\r
172                 time = cal.getTimeInMillis();\r
173             } else if (tzobj instanceof java.util.TimeZone) {\r
174                 java.util.GregorianCalendar cal = new java.util.GregorianCalendar();\r
175                 cal.setTimeZone((java.util.TimeZone)tzobj);\r
176                 cal.clear();\r
177                 cal.set(year, month, dayOfMonth, hour, minute, second);\r
178                 time = cal.getTimeInMillis();\r
179             } else {\r
180                 throw new IllegalStateException("Unsupported TimeZone implementation");\r
181             }\r
182             return time;\r
183         }\r
184     }\r
185 \r
186     public class DumpFormatter {\r
187         private SimpleTimeZone stz = new SimpleTimeZone(0, "");\r
188         private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd EEE HH:mm:ss", ULocale.US);\r
189         private DecimalFormat decf;\r
190 \r
191         public DumpFormatter() {\r
192             DecimalFormatSymbols decfs = new DecimalFormatSymbols(ULocale.US);\r
193             decf = new DecimalFormat("00", decfs);\r
194         }\r
195 \r
196         public String format(long time, int offset, boolean isDst) {\r
197             StringBuffer buf = new StringBuffer();\r
198             stz.setRawOffset(offset);\r
199             sdf.setTimeZone(stz);\r
200             buf.append(sdf.format(new Date(time)));\r
201             if (offset < 0) {\r
202                 buf.append("-");\r
203                 offset = -offset;\r
204             } else {\r
205                 buf.append("+");\r
206             }\r
207 \r
208             int hour, min, sec;\r
209 \r
210             offset /= 1000;\r
211             sec = offset % 60;\r
212             offset = (offset - sec) / 60;\r
213             min = offset % 60;\r
214             hour = offset / 60;\r
215 \r
216             buf.append(decf.format(hour));\r
217             buf.append(decf.format(min));\r
218             buf.append(decf.format(sec));\r
219 \r
220             buf.append("[DST=");\r
221             buf.append(isDst ? "1" : "0");\r
222             buf.append("]");\r
223             return buf.toString();\r
224         }\r
225     }\r
226 \r
227     /*\r
228      * Usage:\r
229      * \r
230      * java -cp icu4j.jar com.ibm.icu.dev.tool.timezone [-j] [-a] [-c[<low_year>,]<high_year>] [-d<dir>] [-l<sep>] [<zone_name> [<zone_name>]]\r
231      * \r
232      * Options:\r
233      *      -j      : Use JDK TimeZone.  By default, ICU TimeZone is used.\r
234      *      -a      : Dump all available zones.\r
235      *      -c[<low_year>,]<high_year>\r
236      *              : When specified, dump transitions starting <low_year> (inclusive) up to\r
237      *                <high_year> (exclusive).  The default values are 1902(low) and 2038(high).\r
238      *      -d<dir> : When specified, write transitions in a file under the directory for each zone.\r
239      *      -l<sep> : New line code type CR/LF/CRLF.\r
240      */\r
241     public static void main(String[] args) {\r
242         boolean jdk = false;\r
243         int low = 1902;\r
244         int high = 2038;\r
245         List idlist = new ArrayList();\r
246         boolean all = false;\r
247         String dir = null;\r
248         String newLineMode = null;\r
249         for (int i = 0; i < args.length; i++) {\r
250             if (args[i].equals("-j")) {\r
251                 jdk = true;\r
252             } else if (args[i].startsWith("-c")) {\r
253                 String val = args[i].substring(2);\r
254                 String[] years = val.split(",");\r
255                 if (years.length == 1) {\r
256                     high = Integer.parseInt(years[0]);\r
257                 } else if (years.length == 2) {\r
258                     low = Integer.parseInt(years[0]);\r
259                     high = Integer.parseInt(years[1]);\r
260                 }\r
261             } else if (args[i].equals("-a")) {\r
262                 all = true;\r
263             } else if (args[i].startsWith("-d")) {\r
264                 dir = args[i].substring(2);\r
265             } else if (args[i].startsWith("-l")) {\r
266                 newLineMode = args[i].substring(2);\r
267             } else if (!args[i].startsWith("-")){\r
268                 idlist.add(args[i].trim());\r
269             }\r
270         }\r
271 \r
272         String lineSep = System.getProperty("line.separator");\r
273         if (newLineMode != null && newLineMode.length() > 0) {\r
274             if (newLineMode.equalsIgnoreCase("CR")) {\r
275                 lineSep = "\r";\r
276             } else if (newLineMode.equalsIgnoreCase("LF")) {\r
277                 lineSep = "\n";\r
278             } else if (newLineMode.equalsIgnoreCase("CRLF")) {\r
279                 lineSep = "\r\n";            \r
280             }\r
281         }\r
282         \r
283         String[] tzids = null;\r
284 \r
285         if (all) {\r
286             if (jdk) {\r
287                 tzids = java.util.TimeZone.getAvailableIDs();\r
288             } else {\r
289                 tzids = com.ibm.icu.util.TimeZone.getAvailableIDs();\r
290             }\r
291 \r
292             // sort tzids\r
293             TreeSet set = new TreeSet();\r
294             for (int i = 0; i < tzids.length; i++) {\r
295                 set.add(tzids[i]);\r
296             }\r
297             Iterator it = set.iterator();\r
298             int i = 0;\r
299             while (it.hasNext()) {\r
300                 tzids[i++] = (String)it.next();\r
301             }\r
302         } else {\r
303             int len = idlist.size();\r
304             if (len == 0) {\r
305                 tzids = new String[1];\r
306                 tzids[0] = java.util.TimeZone.getDefault().getID();\r
307             } else {\r
308                 tzids = new String[idlist.size()];\r
309                 idlist.toArray(tzids);\r
310             }            \r
311         }\r
312 \r
313         File dirfile = null;\r
314         if (dir == null || dir.length() == 0) {\r
315             PrintWriter pw = new PrintWriter(System.out);\r
316             try {\r
317                 for (int i = 0; i < tzids.length; i++) {\r
318                     if (i != 0) {\r
319                         pw.println();\r
320                     }\r
321                     pw.write("ZONE: ");\r
322                     pw.write(tzids[i]);\r
323                     pw.println();\r
324                     dumpZone(pw, lineSep, tzids[i], low, high, jdk);\r
325                 }\r
326                 pw.flush();\r
327             } catch (IOException ioe) {\r
328                 ioe.printStackTrace();\r
329             }\r
330         } else {\r
331             dirfile = new File(dir);\r
332             dirfile.mkdirs();\r
333 \r
334             try {\r
335                 for (int i = 0; i < tzids.length; i++) {\r
336                     FileOutputStream fos = new FileOutputStream(new File(dirfile, tzids[i].replace('/', '-')));\r
337                     Writer w = new BufferedWriter(new OutputStreamWriter(fos));\r
338                     dumpZone(w, lineSep, tzids[i], low, high, jdk);\r
339                     w.close();\r
340                 }\r
341             } catch (IOException ioe) {\r
342                 ioe.printStackTrace();\r
343             }\r
344         }\r
345     }\r
346 \r
347     private static void dumpZone(Writer w, String lineSep, String tzid, int low, int high, boolean isJdk) throws IOException {\r
348         ICUZDump dumper = new ICUZDump();\r
349         Object tzimpl;\r
350         if (isJdk) {\r
351             tzimpl = java.util.TimeZone.getTimeZone(tzid);\r
352         } else {\r
353             tzimpl = com.ibm.icu.util.TimeZone.getTimeZone(tzid);\r
354         }\r
355         dumper.setTimeZone(tzimpl);\r
356         dumper.setLowYear(low);\r
357         dumper.setHighYear(high);\r
358         dumper.setLineSeparator(lineSep);\r
359         dumper.dump(w);\r
360     }\r
361 }\r