]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/datefmt.cpp
ICU-6.2.14.tar.gz
[apple/icu.git] / icuSources / i18n / datefmt.cpp
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
374ca955 3* Copyright (C) 1997-2004, International Business Machines Corporation and *
b75a7d8f
A
4* others. All Rights Reserved. *
5*******************************************************************************
6*
7* File DATEFMT.CPP
8*
9* Modification History:
10*
11* Date Name Description
12* 02/19/97 aliu Converted from java.
13* 03/31/97 aliu Modified extensively to work with 50 locales.
14* 04/01/97 aliu Added support for centuries.
15* 08/12/97 aliu Fixed operator== to use Calendar::equivalentTo.
16* 07/20/98 stephen Changed ParsePosition initialization
17********************************************************************************
18*/
19
20#include "unicode/utypes.h"
21
22#if !UCONFIG_NO_FORMATTING
23
374ca955 24#include "unicode/ures.h"
b75a7d8f
A
25#include "unicode/datefmt.h"
26#include "unicode/smpdtfmt.h"
27
374ca955
A
28#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
29#include <stdio.h>
30#endif
31
b75a7d8f
A
32// *****************************************************************************
33// class DateFormat
34// *****************************************************************************
35
36U_NAMESPACE_BEGIN
37
38DateFormat::DateFormat()
39: fCalendar(0),
40 fNumberFormat(0)
41{
42}
43
44//----------------------------------------------------------------------
45
46DateFormat::DateFormat(const DateFormat& other)
47: Format(other),
48 fCalendar(0),
49 fNumberFormat(0)
50{
51 *this = other;
52}
53
54//----------------------------------------------------------------------
55
56DateFormat& DateFormat::operator=(const DateFormat& other)
57{
58 if (this != &other)
59 {
60 delete fCalendar;
61 delete fNumberFormat;
62 if(other.fCalendar) {
63 fCalendar = other.fCalendar->clone();
64 } else {
65 fCalendar = NULL;
66 }
67 if(other.fNumberFormat) {
68 fNumberFormat = (NumberFormat*)other.fNumberFormat->clone();
69 } else {
70 fNumberFormat = NULL;
71 }
72 }
73 return *this;
74}
75
76//----------------------------------------------------------------------
77
78DateFormat::~DateFormat()
79{
80 delete fCalendar;
81 delete fNumberFormat;
82}
83
84//----------------------------------------------------------------------
85
86UBool
87DateFormat::operator==(const Format& other) const
88{
89 // This protected comparison operator should only be called by subclasses
90 // which have confirmed that the other object being compared against is
91 // an instance of a sublcass of DateFormat. THIS IS IMPORTANT.
92
374ca955 93 // Format::operator== guarantees that this cast is safe
b75a7d8f
A
94 DateFormat* fmt = (DateFormat*)&other;
95
96 return (this == fmt) ||
374ca955 97 (Format::operator==(other) &&
b75a7d8f 98 fCalendar&&(fCalendar->isEquivalentTo(*fmt->fCalendar)) &&
374ca955 99 (fNumberFormat && *fNumberFormat == *fmt->fNumberFormat));
b75a7d8f
A
100}
101
102//----------------------------------------------------------------------
103
104UnicodeString&
105DateFormat::format(const Formattable& obj,
106 UnicodeString& appendTo,
107 FieldPosition& fieldPosition,
108 UErrorCode& status) const
109{
110 if (U_FAILURE(status)) return appendTo;
111
112 // if the type of the Formattable is double or long, treat it as if it were a Date
113 UDate date = 0;
114 switch (obj.getType())
115 {
116 case Formattable::kDate:
117 date = obj.getDate();
118 break;
119 case Formattable::kDouble:
120 date = (UDate)obj.getDouble();
121 break;
122 case Formattable::kLong:
123 date = (UDate)obj.getLong();
124 break;
125 default:
126 status = U_ILLEGAL_ARGUMENT_ERROR;
127 return appendTo;
128 }
129
130 // Is this right?
131 //if (fieldPosition.getBeginIndex() == fieldPosition.getEndIndex())
132 // status = U_ILLEGAL_ARGUMENT_ERROR;
133
134 return format(date, appendTo, fieldPosition);
135}
136
137//----------------------------------------------------------------------
138
139UnicodeString&
140DateFormat::format(UDate date, UnicodeString& appendTo, FieldPosition& fieldPosition) const {
141 if (fCalendar != NULL) {
142 // Use our calendar instance
143 UErrorCode ec = U_ZERO_ERROR;
144 fCalendar->setTime(date, ec);
145 if (U_SUCCESS(ec)) {
146 return format(*fCalendar, appendTo, fieldPosition);
147 }
148 }
149 return appendTo;
150}
151
152//----------------------------------------------------------------------
153
154UnicodeString&
155DateFormat::format(UDate date, UnicodeString& appendTo) const
156{
157 // Note that any error information is just lost. That's okay
158 // for this convenience method.
159 FieldPosition fpos(0);
160 return format(date, appendTo, fpos);
161}
162
163//----------------------------------------------------------------------
164
165UDate
166DateFormat::parse(const UnicodeString& text,
167 ParsePosition& pos) const
168{
169 if (fCalendar != NULL) {
170 int32_t start = pos.getIndex();
171 fCalendar->clear();
172 parse(text, *fCalendar, pos);
173 if (pos.getIndex() != start) {
174 UErrorCode ec = U_ZERO_ERROR;
175 UDate d = fCalendar->getTime(ec);
176 if (U_SUCCESS(ec)) {
177 return d; // Successful function exit
178 }
179 // We arrive here if fCalendar is non-lenient and there
180 // is an out-of-range field. We don't know which field
181 // was illegal so we set the error index to the start.
182 pos.setIndex(start);
183 pos.setErrorIndex(start);
184 }
185 }
186 return 0; // Error return UDate is 0 (the epoch)
187}
188
189//----------------------------------------------------------------------
190
191UDate
192DateFormat::parse(const UnicodeString& text,
193 UErrorCode& status) const
194{
195 if (U_FAILURE(status)) return 0;
196
197 ParsePosition pos(0);
198 UDate result = parse(text, pos);
374ca955
A
199 if (pos.getIndex() == 0) {
200#if defined (U_DEBUG_CAL)
201 fprintf(stderr, "%s:%d - - failed to parse - err index %d\n"
202 , __FILE__, __LINE__, pos.getErrorIndex() );
203#endif
204 status = U_ILLEGAL_ARGUMENT_ERROR;
205 }
b75a7d8f
A
206 return result;
207}
208
209//----------------------------------------------------------------------
210
211void
212DateFormat::parseObject(const UnicodeString& source,
213 Formattable& result,
214 ParsePosition& pos) const
215{
216 result.setDate(parse(source, pos));
217}
218
219//----------------------------------------------------------------------
220
374ca955 221DateFormat* U_EXPORT2
b75a7d8f
A
222DateFormat::createTimeInstance(DateFormat::EStyle style,
223 const Locale& aLocale)
224{
225 return create(style, kNone, aLocale);
226}
227
228//----------------------------------------------------------------------
229
374ca955 230DateFormat* U_EXPORT2
b75a7d8f
A
231DateFormat::createDateInstance(DateFormat::EStyle style,
232 const Locale& aLocale)
233{
374ca955
A
234 // +4 to set the correct index for getting data out of
235 // LocaleElements.
236 if(style != kNone)
237 {
238 style = (EStyle) (style + kDateOffset);
239 }
240 return create(kNone, (EStyle) (style), aLocale);
b75a7d8f
A
241}
242
243//----------------------------------------------------------------------
244
374ca955 245DateFormat* U_EXPORT2
b75a7d8f
A
246DateFormat::createDateTimeInstance(EStyle dateStyle,
247 EStyle timeStyle,
248 const Locale& aLocale)
249{
374ca955
A
250 if(dateStyle != kNone)
251 {
252 dateStyle = (EStyle) (dateStyle + kDateOffset);
253 }
254 return create(timeStyle, dateStyle, aLocale);
b75a7d8f
A
255}
256
257//----------------------------------------------------------------------
258
374ca955 259DateFormat* U_EXPORT2
b75a7d8f
A
260DateFormat::createInstance()
261{
262 return create(kShort, (EStyle) (kShort + kDateOffset), Locale::getDefault());
263}
264
265//----------------------------------------------------------------------
266
374ca955 267DateFormat* U_EXPORT2
b75a7d8f
A
268DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale)
269{
270 // Try to create a SimpleDateFormat of the desired style.
271 UErrorCode status = U_ZERO_ERROR;
272 SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status);
273 if (U_SUCCESS(status)) return f;
274 delete f;
275
276 // If that fails, try to create a format using the default pattern and
277 // the DateFormatSymbols for this locale.
278 status = U_ZERO_ERROR;
279 f = new SimpleDateFormat(locale, status);
280 if (U_SUCCESS(status)) return f;
281 delete f;
282
283 // This should never really happen, because the preceding constructor
284 // should always succeed. If the resource data is unavailable, a last
285 // resort object should be returned.
286 return 0;
287}
288
289//----------------------------------------------------------------------
290
374ca955 291const Locale* U_EXPORT2
b75a7d8f
A
292DateFormat::getAvailableLocales(int32_t& count)
293{
294 // Get the list of installed locales.
295 // Even if root has the correct date format for this locale,
296 // it's still a valid locale (we don't worry about data fallbacks).
297 return Locale::getAvailableLocales(count);
298}
299
300//----------------------------------------------------------------------
301
302void
303DateFormat::adoptCalendar(Calendar* newCalendar)
304{
305 delete fCalendar;
306 fCalendar = newCalendar;
307}
308
309//----------------------------------------------------------------------
310void
311DateFormat::setCalendar(const Calendar& newCalendar)
312{
313 adoptCalendar(newCalendar.clone());
314}
315
316//----------------------------------------------------------------------
317
318const Calendar*
319DateFormat::getCalendar() const
320{
321 return fCalendar;
322}
323
324//----------------------------------------------------------------------
325
326void
327DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat)
328{
329 delete fNumberFormat;
330 fNumberFormat = newNumberFormat;
331 newNumberFormat->setParseIntegerOnly(TRUE);
332}
333//----------------------------------------------------------------------
334
335void
336DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)
337{
338 adoptNumberFormat((NumberFormat*)newNumberFormat.clone());
339}
340
341//----------------------------------------------------------------------
342
343const NumberFormat*
344DateFormat::getNumberFormat() const
345{
346 return fNumberFormat;
347}
348
349//----------------------------------------------------------------------
350
351void
352DateFormat::adoptTimeZone(TimeZone* zone)
353{
354 fCalendar->adoptTimeZone(zone);
355}
356//----------------------------------------------------------------------
357
358void
359DateFormat::setTimeZone(const TimeZone& zone)
360{
361 fCalendar->setTimeZone(zone);
362}
363
364//----------------------------------------------------------------------
365
366const TimeZone&
367DateFormat::getTimeZone() const
368{
369 return fCalendar->getTimeZone();
370}
371
372//----------------------------------------------------------------------
373
374void
375DateFormat::setLenient(UBool lenient)
376{
377 fCalendar->setLenient(lenient);
378}
379
380//----------------------------------------------------------------------
381
382UBool
383DateFormat::isLenient() const
384{
385 return fCalendar->isLenient();
386}
387
388U_NAMESPACE_END
389
390#endif /* #if !UCONFIG_NO_FORMATTING */
391
392//eof