1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2009, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/*
7* File CALTZTST.H
8*
9* Modification History:
10*
11*   Date        Name        Description
12*   08/06/97    aliu        Creation.
13********************************************************************************
14*/
15
16#include "unicode/utypes.h"
17
18#if !UCONFIG_NO_FORMATTING
19
20#include "caltztst.h"
21#include "unicode/smpdtfmt.h"
22#include "mutex.h"
23
24DateFormat*         CalendarTimeZoneTest::fgDateFormat = 0;
25Calendar*           CalendarTimeZoneTest::fgCalendar   = 0;
26
27UBool CalendarTimeZoneTest::failure(UErrorCode status, const char* msg, UBool possibleDataError)
28{
29    if (U_FAILURE(status))
30    {
31        if (possibleDataError) {
32            dataerrln(UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status));
33        } else {
34            errcheckln(status, UnicodeString("FAIL: ") + msg + " failed, error " + u_errorName(status));
35        }
36        return TRUE;
37    }
38    return FALSE;
39}
40
41DateFormat*   CalendarTimeZoneTest::getDateFormat()
42{
43    DateFormat *theFormat = 0;
44
45    if (fgDateFormat != 0) // if there's something in the cache
46    {
47        Mutex lock;
48
49        if (fgDateFormat != 0) // Someone might have grabbed it.
50        {
51            theFormat = fgDateFormat;
52            fgDateFormat = 0; // We have exclusive right to this formatter.
53        }
54    }
55
56    if(theFormat == 0) // If we weren't able to pull it out of the cache, then we have to create it.
57    {
58        UErrorCode status = U_ZERO_ERROR;
59        theFormat = new SimpleDateFormat(UnicodeString("EEE MMM dd HH:mm:ss zzz yyyy"), status);
60        if (U_FAILURE(status))
61        {
62            delete theFormat;
63            theFormat = 0;
64            errcheckln(status, "FAIL: Could not create SimpleDateFormat - %s", u_errorName(status));
65        }
66    }
67
68    return theFormat;
69}
70
71void CalendarTimeZoneTest::releaseDateFormat(DateFormat *adopt)
72{
73    if(fgDateFormat == 0) // If the cache is empty we must add it back.
74    {
75        Mutex lock;
76
77        if(fgDateFormat == 0)
78        {
79            fgDateFormat = adopt;
80            adopt = 0;
81        }
82    }
83    else {
84        delete adopt;
85    }
86}
87
88Calendar*  CalendarTimeZoneTest::getCalendar()
89{
90    Calendar *theCalendar = 0;
91
92    if (fgCalendar != 0) // if there's something in the cache
93    {
94        Mutex lock;
95
96        if (fgCalendar != 0) // Someone might have grabbed it.
97        {
98            theCalendar = fgCalendar;
99            fgCalendar = 0; // We have exclusive right to this calendar.
100        }
101    }
102
103    if(theCalendar == 0) // If we weren't able to pull it out of the cache, then we have to create it.
104    {
105        UErrorCode status = U_ZERO_ERROR;
106        theCalendar = Calendar::createInstance(status);
107        if (U_FAILURE(status))
108        {
109            delete theCalendar;
110            theCalendar = 0;
111            errln("FAIL: Calendar::createInstance failed");
112        }
113    }
114    return theCalendar;
115}
116
117void CalendarTimeZoneTest::releaseCalendar(Calendar* adopt)
118{
119    if(fgCalendar == 0) // If the cache is empty we must add it back.
120    {
121        Mutex lock;
122
123        if(fgCalendar == 0)
124        {
125            fgCalendar = adopt;
126            adopt = 0;
127        }
128    }
129    else
130    {
131        delete adopt;
132    }
133}
134
135// Utility method for formatting dates for printing; useful for Java->C++ conversion.
136// Tries to mimic the Java Date.toString() format.
137UnicodeString
138CalendarTimeZoneTest::dateToString(UDate d)
139{
140    UnicodeString str;
141    return dateToString(d, str);
142}
143
144UnicodeString&
145CalendarTimeZoneTest::dateToString(UDate d, UnicodeString& str)
146{
147    str.remove();
148    DateFormat* format = getDateFormat();
149    if (format == 0)
150    {
151        str += "DATE_FORMAT_FAILURE";
152        return str;
153    }
154    format->format(d, str);
155    releaseDateFormat(format);
156    return str;
157}
158
159UnicodeString&
160CalendarTimeZoneTest::dateToString(UDate d, UnicodeString& str,
161                                   const TimeZone& tz)
162{
163    str.remove();
164    DateFormat* format = getDateFormat();
165    if (format == 0)
166    {
167        str += "DATE_FORMAT_FAILURE";
168        return str;
169    }
170    TimeZone* save = format->getTimeZone().clone();
171    format->setTimeZone(tz);
172    format->format(d, str);
173    format->adoptTimeZone(save);
174    releaseDateFormat(format);
175    return str;
176}
177
178// Utility methods to create a date.  This is useful for converting Java constructs
179// which create a Date object.
180UDate
181CalendarTimeZoneTest::date(int32_t y, int32_t m, int32_t d, int32_t hr, int32_t min, int32_t sec)
182{
183    Calendar* cal = getCalendar();
184    if (cal == 0) return 0.0;
185    cal->clear();
186    cal->set(1900 + y, m, d, hr, min, sec); // Add 1900 to follow java.util.Date protocol
187    UErrorCode status = U_ZERO_ERROR;
188    UDate dt = cal->getTime(status);
189    releaseCalendar(cal);
190    if (U_FAILURE(status))
191    {
192        errln("FAIL: Calendar::getTime failed");
193        return 0.0;
194    }
195    return dt;
196}
197
198// Utility methods to create a date.  The returned Date is UTC rather than local.
199/*Date
200CalendarTimeZoneTest::utcDate(int32_t y, int32_t m, int32_t d, int32_t hr, int32_t min, int32_t sec)
201{
202    Calendar* cal = getCalendar();
203    if (cal == 0) return 0.0;
204    UErrorCode status = U_ZERO_ERROR;
205    Date dt = date(y, m, d, hr, min, sec) +
206        cal->get(Calendar::ZONE_OFFSET, status) -
207        cal->get(Calendar::DST_OFFSET, status);
208    releaseCalendar(cal);
209    if (U_FAILURE(status))
210    {
211        errln("FAIL: Calendar::get failed");
212        return 0.0;
213    }
214    return dt;
215}*/
216
217// Mimics Date.getYear() etc.
218void
219CalendarTimeZoneTest::dateToFields(UDate date, int32_t& y, int32_t& m, int32_t& d, int32_t& hr, int32_t& min, int32_t& sec)
220{
221    Calendar* cal = getCalendar();
222    if (cal == 0) return;
223    UErrorCode status = U_ZERO_ERROR;
224    cal->setTime(date, status);
225    y = cal->get(UCAL_YEAR, status) - 1900;
226    m = cal->get(UCAL_MONTH, status);
227    d = cal->get(UCAL_DATE, status);
228    hr = cal->get(UCAL_HOUR_OF_DAY, status);
229    min = cal->get(UCAL_MINUTE, status);
230    sec = cal->get(UCAL_SECOND, status);
231    releaseCalendar(cal);
232}
233
234void CalendarTimeZoneTest::cleanup()
235{
236    delete fgDateFormat;
237    fgDateFormat = 0;
238    delete fgCalendar;
239    fgCalendar   = 0;
240}
241
242#endif /* #if !UCONFIG_NO_FORMATTING */
243
244//eof
245