]>
git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/datefmt.cpp
2 *******************************************************************************
3 * Copyright (C) 1997-2006, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
9 * Modification History:
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 ********************************************************************************
20 #include "unicode/utypes.h"
22 #if !UCONFIG_NO_FORMATTING
24 #include "unicode/ures.h"
25 #include "unicode/datefmt.h"
26 #include "unicode/smpdtfmt.h"
31 #if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
35 // *****************************************************************************
37 // *****************************************************************************
41 DateFormat::DateFormat()
47 //----------------------------------------------------------------------
49 DateFormat::DateFormat(const DateFormat
& other
)
57 //----------------------------------------------------------------------
59 DateFormat
& DateFormat::operator=(const DateFormat
& other
)
66 fCalendar
= other
.fCalendar
->clone();
70 if(other
.fNumberFormat
) {
71 fNumberFormat
= (NumberFormat
*)other
.fNumberFormat
->clone();
79 //----------------------------------------------------------------------
81 DateFormat::~DateFormat()
87 //----------------------------------------------------------------------
90 DateFormat::operator==(const Format
& other
) const
92 // This protected comparison operator should only be called by subclasses
93 // which have confirmed that the other object being compared against is
94 // an instance of a sublcass of DateFormat. THIS IS IMPORTANT.
96 // Format::operator== guarantees that this cast is safe
97 DateFormat
* fmt
= (DateFormat
*)&other
;
99 return (this == fmt
) ||
100 (Format::operator==(other
) &&
101 fCalendar
&&(fCalendar
->isEquivalentTo(*fmt
->fCalendar
)) &&
102 (fNumberFormat
&& *fNumberFormat
== *fmt
->fNumberFormat
));
105 //----------------------------------------------------------------------
108 DateFormat::format(const Formattable
& obj
,
109 UnicodeString
& appendTo
,
110 FieldPosition
& fieldPosition
,
111 UErrorCode
& status
) const
113 if (U_FAILURE(status
)) return appendTo
;
115 // if the type of the Formattable is double or long, treat it as if it were a Date
117 switch (obj
.getType())
119 case Formattable::kDate
:
120 date
= obj
.getDate();
122 case Formattable::kDouble
:
123 date
= (UDate
)obj
.getDouble();
125 case Formattable::kLong
:
126 date
= (UDate
)obj
.getLong();
129 status
= U_ILLEGAL_ARGUMENT_ERROR
;
134 //if (fieldPosition.getBeginIndex() == fieldPosition.getEndIndex())
135 // status = U_ILLEGAL_ARGUMENT_ERROR;
137 return format(date
, appendTo
, fieldPosition
);
140 //----------------------------------------------------------------------
143 DateFormat::format(UDate date
, UnicodeString
& appendTo
, FieldPosition
& fieldPosition
) const {
144 if (fCalendar
!= NULL
) {
145 // Use our calendar instance
146 UErrorCode ec
= U_ZERO_ERROR
;
147 fCalendar
->setTime(date
, ec
);
149 return format(*fCalendar
, appendTo
, fieldPosition
);
155 //----------------------------------------------------------------------
158 DateFormat::format(UDate date
, UnicodeString
& appendTo
) const
160 // Note that any error information is just lost. That's okay
161 // for this convenience method.
162 FieldPosition
fpos(0);
163 return format(date
, appendTo
, fpos
);
166 //----------------------------------------------------------------------
169 DateFormat::parse(const UnicodeString
& text
,
170 ParsePosition
& pos
) const
172 if (fCalendar
!= NULL
) {
173 int32_t start
= pos
.getIndex();
175 parse(text
, *fCalendar
, pos
);
176 if (pos
.getIndex() != start
) {
177 UErrorCode ec
= U_ZERO_ERROR
;
178 UDate d
= fCalendar
->getTime(ec
);
180 return d
; // Successful function exit
182 // We arrive here if fCalendar is non-lenient and there
183 // is an out-of-range field. We don't know which field
184 // was illegal so we set the error index to the start.
186 pos
.setErrorIndex(start
);
189 return 0; // Error return UDate is 0 (the epoch)
192 //----------------------------------------------------------------------
195 DateFormat::parse(const UnicodeString
& text
,
196 UErrorCode
& status
) const
198 if (U_FAILURE(status
)) return 0;
200 ParsePosition
pos(0);
201 UDate result
= parse(text
, pos
);
202 if (pos
.getIndex() == 0) {
203 #if defined (U_DEBUG_CAL)
204 fprintf(stderr
, "%s:%d - - failed to parse - err index %d\n"
205 , __FILE__
, __LINE__
, pos
.getErrorIndex() );
207 status
= U_ILLEGAL_ARGUMENT_ERROR
;
212 //----------------------------------------------------------------------
215 DateFormat::parseObject(const UnicodeString
& source
,
217 ParsePosition
& pos
) const
219 result
.setDate(parse(source
, pos
));
222 //----------------------------------------------------------------------
224 DateFormat
* U_EXPORT2
225 DateFormat::createTimeInstance(DateFormat::EStyle style
,
226 const Locale
& aLocale
)
228 return create(style
, kNone
, aLocale
);
231 //----------------------------------------------------------------------
233 DateFormat
* U_EXPORT2
234 DateFormat::createDateInstance(DateFormat::EStyle style
,
235 const Locale
& aLocale
)
237 // +4 to set the correct index for getting data out of
241 style
= (EStyle
) (style
+ kDateOffset
);
243 return create(kNone
, (EStyle
) (style
), aLocale
);
246 //----------------------------------------------------------------------
248 DateFormat
* U_EXPORT2
249 DateFormat::createDateTimeInstance(EStyle dateStyle
,
251 const Locale
& aLocale
)
253 if(dateStyle
!= kNone
)
255 dateStyle
= (EStyle
) (dateStyle
+ kDateOffset
);
257 return create(timeStyle
, dateStyle
, aLocale
);
260 //----------------------------------------------------------------------
262 DateFormat
* U_EXPORT2
263 DateFormat::createInstance()
265 return create(kShort
, (EStyle
) (kShort
+ kDateOffset
), Locale::getDefault());
268 //----------------------------------------------------------------------
270 DateFormat
* U_EXPORT2
271 DateFormat::create(EStyle timeStyle
, EStyle dateStyle
, const Locale
& locale
)
273 UErrorCode status
= U_ZERO_ERROR
;
276 int32_t count
= locale
.getKeywordValue("compat", buffer
, sizeof(buffer
), status
);
278 // if the locale has "@compat=host", create a host-specific DateFormat...
279 if (count
> 0 && uprv_strcmp(buffer
, "host") == 0) {
280 Win32DateFormat
*f
= new Win32DateFormat(timeStyle
, dateStyle
, locale
, status
);
282 if (U_SUCCESS(status
)) {
291 // Try to create a SimpleDateFormat of the desired style.
292 SimpleDateFormat
*f
= new SimpleDateFormat(timeStyle
, dateStyle
, locale
, status
);
293 if (U_SUCCESS(status
)) return f
;
296 // If that fails, try to create a format using the default pattern and
297 // the DateFormatSymbols for this locale.
298 status
= U_ZERO_ERROR
;
299 f
= new SimpleDateFormat(locale
, status
);
300 if (U_SUCCESS(status
)) return f
;
303 // This should never really happen, because the preceding constructor
304 // should always succeed. If the resource data is unavailable, a last
305 // resort object should be returned.
309 //----------------------------------------------------------------------
311 const Locale
* U_EXPORT2
312 DateFormat::getAvailableLocales(int32_t& count
)
314 // Get the list of installed locales.
315 // Even if root has the correct date format for this locale,
316 // it's still a valid locale (we don't worry about data fallbacks).
317 return Locale::getAvailableLocales(count
);
320 //----------------------------------------------------------------------
323 DateFormat::adoptCalendar(Calendar
* newCalendar
)
326 fCalendar
= newCalendar
;
329 //----------------------------------------------------------------------
331 DateFormat::setCalendar(const Calendar
& newCalendar
)
333 adoptCalendar(newCalendar
.clone());
336 //----------------------------------------------------------------------
339 DateFormat::getCalendar() const
344 //----------------------------------------------------------------------
347 DateFormat::adoptNumberFormat(NumberFormat
* newNumberFormat
)
349 delete fNumberFormat
;
350 fNumberFormat
= newNumberFormat
;
351 newNumberFormat
->setParseIntegerOnly(TRUE
);
353 //----------------------------------------------------------------------
356 DateFormat::setNumberFormat(const NumberFormat
& newNumberFormat
)
358 adoptNumberFormat((NumberFormat
*)newNumberFormat
.clone());
361 //----------------------------------------------------------------------
364 DateFormat::getNumberFormat() const
366 return fNumberFormat
;
369 //----------------------------------------------------------------------
372 DateFormat::adoptTimeZone(TimeZone
* zone
)
374 fCalendar
->adoptTimeZone(zone
);
376 //----------------------------------------------------------------------
379 DateFormat::setTimeZone(const TimeZone
& zone
)
381 fCalendar
->setTimeZone(zone
);
384 //----------------------------------------------------------------------
387 DateFormat::getTimeZone() const
389 return fCalendar
->getTimeZone();
392 //----------------------------------------------------------------------
395 DateFormat::setLenient(UBool lenient
)
397 fCalendar
->setLenient(lenient
);
400 //----------------------------------------------------------------------
403 DateFormat::isLenient() const
405 return fCalendar
->isLenient();
410 #endif /* #if !UCONFIG_NO_FORMATTING */