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