1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Copyright (C) 2007, International Business Machines
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*******************************************************************************
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   file name:  icuzdump.cpp
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   encoding:   US-ASCII
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   tab size:   8 (not used)
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   indentation:4
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   created on: 2007-04-02
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   created by: Yoshito Umaoka
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   This tool write out timezone transitions for ICU timezone.  This tool
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   is used as a part of tzdata update process to check if ICU timezone
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*   code works as well as the corresponding Olson stock localtime/zdump.
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <cstdlib>
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <cstring>
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <fstream>
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <sstream>
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <iostream>
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h"
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/timezone.h"
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/simpletz.h"
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/smpdtfmt.h"
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/decimfmt.h"
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/gregocal.h"
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustream.h"
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/putil.h"
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uoptions.h"
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruusing namespace std;
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass DumpFormatter {
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DumpFormatter() {
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        stz = new SimpleTimeZone(0, "");
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        sdf = new SimpleDateFormat((UnicodeString)"yyyy-MM-dd EEE HH:mm:ss", Locale::getEnglish(), status);
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getEnglish(), status);
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        decf = new DecimalFormat("00", symbols, status);
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ~DumpFormatter() {
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString& format(UDate time, int32_t offset, UBool isDst, UnicodeString& appendTo) {
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        stz->setRawOffset(offset);
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        sdf->setTimeZone(*stz);
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UnicodeString str = sdf->format(time, appendTo);
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (offset < 0) {
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            appendTo += "-";
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            offset = -offset;
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            appendTo += "+";
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t hour, min, sec;
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offset /= 1000;
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        sec = offset % 60;
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        offset = (offset - sec) / 60;
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        min = offset % 60;
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        hour = offset / 60;
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        decf->format(hour, appendTo);
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        decf->format(min, appendTo);
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        decf->format(sec, appendTo);
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        appendTo += "[DST=";
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (isDst) {
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            appendTo += "1";
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            appendTo += "0";
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        appendTo += "]";
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return appendTo;
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate:
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    SimpleTimeZone*     stz;
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    SimpleDateFormat*   sdf;
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DecimalFormat*      decf;
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass ICUZDump {
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ICUZDump() {
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        formatter = new DumpFormatter();
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        loyear = 1902;
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        hiyear = 2050;
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        tick = 1000;
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        linesep = NULL;
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ~ICUZDump() {
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void setLowYear(int32_t lo) {
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        loyear = lo;
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void setHighYear(int32_t hi) {
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        hiyear = hi;
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void setTick(int32_t t) {
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        tick = t;
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void setTimeZone(TimeZone* tz) {
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        timezone = tz;
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void setDumpFormatter(DumpFormatter* fmt) {
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        formatter = fmt;
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void setLineSeparator(const char* sep) {
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        linesep = sep;
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void dump(ostream& out) {
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UDate SEARCH_INCREMENT = 12 * 60 * 60 * 1000; // half day
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UDate t, cutlo, cuthi;
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        int32_t rawOffset, dstOffset;
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UnicodeString str;
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        getCutOverTimes(cutlo, cuthi);
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        t = cutlo;
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        timezone->getOffset(t, FALSE, rawOffset, dstOffset, status);
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        while (t < cuthi) {
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            int32_t newRawOffset, newDstOffset;
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UDate newt = t + SEARCH_INCREMENT;
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            timezone->getOffset(newt, FALSE, newRawOffset, newDstOffset, status);
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UBool bSameOffset = (rawOffset + dstOffset) == (newRawOffset + newDstOffset);
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UBool bSameDst = ((dstOffset != 0) && (newDstOffset != 0)) || ((dstOffset == 0) && (newDstOffset == 0));
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (!bSameOffset || !bSameDst) {
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // find the boundary
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UDate lot = t;
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                UDate hit = newt;
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                while (true) {
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    int32_t diff = (int32_t)(hit - lot);
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (diff <= tick) {
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        break;
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    UDate medt = lot + ((diff / 2) / tick) * tick;
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    int32_t medRawOffset, medDstOffset;
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    timezone->getOffset(medt, FALSE, medRawOffset, medDstOffset, status);
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    bSameOffset = (rawOffset + dstOffset) == (medRawOffset + medDstOffset);
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    bSameDst = ((dstOffset != 0) && (medDstOffset != 0)) || ((dstOffset == 0) && (medDstOffset == 0));
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (!bSameOffset || !bSameDst) {
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        hit = medt;
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    } else {
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        lot = medt;
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // write out the boundary
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                str.remove();
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                formatter->format(lot, rawOffset + dstOffset, (dstOffset == 0 ? FALSE : TRUE), str);
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                out << str << " > ";
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                str.remove();
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                formatter->format(hit, newRawOffset + newDstOffset, (newDstOffset == 0 ? FALSE : TRUE), str);
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                out << str;
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (linesep != NULL) {
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    out << linesep;
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else {
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    out << endl;
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                rawOffset = newRawOffset;
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                dstOffset = newDstOffset;
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            t = newt;
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate:
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void getCutOverTimes(UDate& lo, UDate& hi) {
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UErrorCode status = U_ZERO_ERROR;
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        GregorianCalendar* gcal = new GregorianCalendar(timezone, Locale::getEnglish(), status);
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        gcal->clear();
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        gcal->set(loyear, 0, 1, 0, 0, 0);
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        lo = gcal->getTime(status);
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        gcal->set(hiyear, 0, 1, 0, 0, 0);
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        hi = gcal->getTime(status);
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void dumpZone(ostream& out, const char* linesep, UnicodeString tzid, int32_t low, int32_t high) {
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TimeZone*   timezone;
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     loyear;
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     hiyear;
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t     tick;
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    DumpFormatter*  formatter;
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char*  linesep;
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass ZoneIterator {
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ZoneIterator(UBool bAll = FALSE) {
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (bAll) {
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            zenum = TimeZone::createEnumeration();
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            zenum = NULL;
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            zids = NULL;
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            idx = 0;
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            numids = 1;
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ZoneIterator(const char** ids, int32_t num) {
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        zenum = NULL;
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        zids = ids;
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        idx = 0;
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        numids = num;
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ~ZoneIterator() {
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (zenum != NULL) {
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete zenum;
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TimeZone* next() {
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        TimeZone* tz = NULL;
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (zenum != NULL) {
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UErrorCode status = U_ZERO_ERROR;
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            const UnicodeString* zid = zenum->snext(status);
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (zid != NULL) {
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                tz = TimeZone::createTimeZone(*zid);
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        else {
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (idx < numids) {
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (zids != NULL) {
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    tz = TimeZone::createTimeZone((const UnicodeString&)zids[idx]);
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    tz = TimeZone::createDefault();
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                idx++;
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return tz;
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate:
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char** zids;
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    StringEnumeration* zenum;
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t idx;
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t numids;
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum {
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  kOptHelpH = 0,
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  kOptHelpQuestionMark,
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  kOptAllZones,
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  kOptCutover,
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  kOptDestDir,
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  kOptLineSep
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UOption options[]={
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_HELP_H,
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_HELP_QUESTION_MARK,
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF("allzones", 'a', UOPT_NO_ARG),
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF("cutover", 'c', UOPT_REQUIRES_ARG),
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF("destdir", 'd', UOPT_REQUIRES_ARG),
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF("linesep", 'l', UOPT_REQUIRES_ARG)
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruextern int
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querumain(int argc, char *argv[]) {
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t low = 1902;
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t high = 2038;
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool bAll = FALSE;
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *dir = NULL;
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char *linesep = NULL;
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    U_MAIN_INIT_ARGS(argc, argv);
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    argc = u_parseArgs(argc, argv, sizeof(options)/sizeof(options[0]), options);
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (argc < 0) {
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cerr << "Illegal command line argument(s)" << endl << endl;
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (argc < 0 || options[kOptHelpH].doesOccur || options[kOptHelpQuestionMark].doesOccur) {
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        cerr
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "Usage: icuzdump [-options] [zoneid1 zoneid2 ...]" << endl
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << endl
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\tDump all offset transitions for the specified zones." << endl
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << endl
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "Options:" << endl
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t-a       : Dump all available zones." << endl
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t-d <dir> : When specified, write transitions in a file under" << endl
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t           the directory for each zone." << endl
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t-l <sep> : New line code type used in file outputs. CR or LF (default)"
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t           or CRLF." << endl
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t-c [<low_year>,]<high_year>" << endl
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t         : When specified, dump transitions starting <low_year>" << endl
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t           (inclusive) up to <high_year> (exclusive).  The default" << endl
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            << "\t           values are 1902(low) and 2038(high)." << endl;
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return argc < 0 ? U_ILLEGAL_ARGUMENT_ERROR : U_ZERO_ERROR;
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    bAll = options[kOptAllZones].doesOccur;
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[kOptDestDir].doesOccur) {
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dir = options[kOptDestDir].value;
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[kOptLineSep].doesOccur) {
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (strcmp(options[kOptLineSep].value, "CR") == 0) {
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            linesep = "\r";
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (strcmp(options[kOptLineSep].value, "CRLF") == 0) {
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            linesep = "\r\n";
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else if (strcmp(options[kOptLineSep].value, "LF") == 0) {
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            linesep = "\n";
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (options[kOptCutover].doesOccur) {
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        char* comma = (char*)strchr(options[kOptCutover].value, ',');
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (comma == NULL) {
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            high = atoi(options[kOptCutover].value);
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            *comma = 0;
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            low = atoi(options[kOptCutover].value);
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            high = atoi(comma + 1);
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ICUZDump dumper;
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    dumper.setLowYear(low);
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    dumper.setHighYear(high);
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (dir != NULL && linesep != NULL) {
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // use the specified line separator only for file output
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        dumper.setLineSeparator((const char*)linesep);
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ZoneIterator* zit;
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (bAll) {
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        zit = new ZoneIterator(TRUE);
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (argc <= 1) {
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            zit = new ZoneIterator();
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        } else {
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            zit = new ZoneIterator((const char**)&argv[1], argc - 1);
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UnicodeString id;
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (dir != NULL) {
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // file output
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ostringstream path;
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ios::openmode mode = ios::out;
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (linesep != NULL) {
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            mode |= ios::binary;
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (;;) {
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            TimeZone* tz = zit->next();
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (tz == NULL) {
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            dumper.setTimeZone(tz);
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            tz->getID(id);
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            // target file path
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            path.str("");
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            path << dir << U_FILE_SEP_CHAR;
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            id = id.findAndReplace("/", "-");
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            path << id;
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ofstream* fout = new ofstream(path.str().c_str(), mode);
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (fout->fail()) {
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                cerr << "Cannot open file " << path << endl;
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                delete fout;
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                delete tz;
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            dumper.dump(*fout);
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            fout->close();
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete fout;
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete tz;
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // stdout
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        UBool bFirst = TRUE;
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        for (;;) {
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            TimeZone* tz = zit->next();
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (tz == NULL) {
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                break;
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            dumper.setTimeZone(tz);
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            tz->getID(id);
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (bFirst) {
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                bFirst = FALSE;
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                cout << endl;
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            cout << "ZONE: " << id << endl;
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            dumper.dump(cout);
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete tz;
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    delete zit;
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
424