1/* 2* Copyright (C) 1997-2011, International Business Machines Corporation and 3* others. All Rights Reserved. 4******************************************************************************* 5* 6* File SMPDTFMT.H 7* 8* Modification History: 9* 10* Date Name Description 11* 02/19/97 aliu Converted from java. 12* 07/09/97 helena Make ParsePosition into a class. 13* 07/21/98 stephen Added GMT_PLUS, GMT_MINUS 14* Changed setTwoDigitStartDate to set2DigitYearStart 15* Changed getTwoDigitStartDate to get2DigitYearStart 16* Removed subParseLong 17* Removed getZoneIndex (added in DateFormatSymbols) 18* 06/14/99 stephen Removed fgTimeZoneDataSuffix 19* 10/14/99 aliu Updated class doc to describe 2-digit year parsing 20* {j28 4182066}. 21******************************************************************************* 22*/ 23 24#ifndef SMPDTFMT_H 25#define SMPDTFMT_H 26 27#include "unicode/utypes.h" 28 29/** 30 * \file 31 * \brief C++ API: Format and parse dates in a language-independent manner. 32 */ 33 34#if !UCONFIG_NO_FORMATTING 35 36#include "unicode/datefmt.h" 37 38U_NAMESPACE_BEGIN 39 40class DateFormatSymbols; 41class DateFormat; 42class MessageFormat; 43class FieldPositionHandler; 44class TimeZoneFormat; 45 46/** 47 * 48 * SimpleDateFormat is a concrete class for formatting and parsing dates in a 49 * language-independent manner. It allows for formatting (millis -> text), 50 * parsing (text -> millis), and normalization. Formats/Parses a date or time, 51 * which is the standard milliseconds since 24:00 GMT, Jan 1, 1970. 52 * <P> 53 * Clients are encouraged to create a date-time formatter using DateFormat::getInstance(), 54 * getDateInstance(), getDateInstance(), or getDateTimeInstance() rather than 55 * explicitly constructing an instance of SimpleDateFormat. This way, the client 56 * is guaranteed to get an appropriate formatting pattern for whatever locale the 57 * program is running in. However, if the client needs something more unusual than 58 * the default patterns in the locales, he can construct a SimpleDateFormat directly 59 * and give it an appropriate pattern (or use one of the factory methods on DateFormat 60 * and modify the pattern after the fact with toPattern() and applyPattern(). 61 * <P> 62 * Date/Time format syntax: 63 * <P> 64 * The date/time format is specified by means of a string time pattern. In this 65 * pattern, all ASCII letters are reserved as pattern letters, which are defined 66 * as the following: 67 * <pre> 68 * \code 69 * Symbol Meaning Presentation Example 70 * ------ ------- ------------ ------- 71 * G era designator (Text) AD 72 * y year (Number) 1996 73 * Y year (week of year) (Number) 1997 74 * u extended year (Number) 4601 75 * Q Quarter (Text & Number) Q2 & 02 76 * M month in year (Text & Number) July & 07 77 * d day in month (Number) 10 78 * h hour in am/pm (1~12) (Number) 12 79 * H hour in day (0~23) (Number) 0 80 * m minute in hour (Number) 30 81 * s second in minute (Number) 55 82 * S fractional second (Number) 978 83 * E day of week (Text) Tuesday 84 * e day of week (local 1~7) (Text & Number) Tues & 2 85 * D day in year (Number) 189 86 * F day of week in month (Number) 2 (2nd Wed in July) 87 * w week in year (Number) 27 88 * W week in month (Number) 2 89 * a am/pm marker (Text) PM 90 * k hour in day (1~24) (Number) 24 91 * K hour in am/pm (0~11) (Number) 0 92 * z time zone (Time) Pacific Standard Time 93 * Z time zone (RFC 822) (Number) -0800 94 * v time zone (generic) (Text) Pacific Time 95 * V time zone (abreviation) (Text) PT 96 * VVVV time zone (location) (Text) United States (Los Angeles) 97 * g Julian day (Number) 2451334 98 * A milliseconds in day (Number) 69540000 99 * q stand alone quarter (Text & Number) Q2 & 02 100 * L stand alone month (Text & Number) July & 07 101 * c stand alone day of week (Text & Number) Tuesday & 2 102 * ' escape for text (Delimiter) 'Date=' 103 * '' single quote (Literal) 'o''clock' 104 * \endcode 105 * </pre> 106 * The count of pattern letters determine the format. 107 * <P> 108 * (Text): 4 or more, use full form, <4, use short or abbreviated form if it 109 * exists. (e.g., "EEEE" produces "Monday", "EEE" produces "Mon") 110 * <P> 111 * (Number): the minimum number of digits. Shorter numbers are zero-padded to 112 * this amount (e.g. if "m" produces "6", "mm" produces "06"). Year is handled 113 * specially; that is, if the count of 'y' is 2, the Year will be truncated to 2 digits. 114 * (e.g., if "yyyy" produces "1997", "yy" produces "97".) 115 * Unlike other fields, fractional seconds are padded on the right with zero. 116 * <P> 117 * (Text & Number): 3 or over, use text, otherwise use number. (e.g., "M" produces "1", 118 * "MM" produces "01", "MMM" produces "Jan", and "MMMM" produces "January".) 119 * <P> 120 * Any characters in the pattern that are not in the ranges of ['a'..'z'] and 121 * ['A'..'Z'] will be treated as quoted text. For instance, characters 122 * like ':', '.', ' ', '#' and '@' will appear in the resulting time text 123 * even they are not embraced within single quotes. 124 * <P> 125 * A pattern containing any invalid pattern letter will result in a failing 126 * UErrorCode result during formatting or parsing. 127 * <P> 128 * Examples using the US locale: 129 * <pre> 130 * \code 131 * Format Pattern Result 132 * -------------- ------- 133 * "yyyy.MM.dd G 'at' HH:mm:ss vvvv" ->> 1996.07.10 AD at 15:08:56 Pacific Time 134 * "EEE, MMM d, ''yy" ->> Wed, July 10, '96 135 * "h:mm a" ->> 12:08 PM 136 * "hh 'o''clock' a, zzzz" ->> 12 o'clock PM, Pacific Daylight Time 137 * "K:mm a, vvv" ->> 0:00 PM, PT 138 * "yyyyy.MMMMM.dd GGG hh:mm aaa" ->> 1996.July.10 AD 12:08 PM 139 * \endcode 140 * </pre> 141 * Code Sample: 142 * <pre> 143 * \code 144 * UErrorCode success = U_ZERO_ERROR; 145 * SimpleTimeZone* pdt = new SimpleTimeZone(-8 * 60 * 60 * 1000, "PST"); 146 * pdt->setStartRule( Calendar::APRIL, 1, Calendar::SUNDAY, 2*60*60*1000); 147 * pdt->setEndRule( Calendar::OCTOBER, -1, Calendar::SUNDAY, 2*60*60*1000); 148 * 149 * // Format the current time. 150 * SimpleDateFormat* formatter 151 * = new SimpleDateFormat ("yyyy.MM.dd G 'at' hh:mm:ss a zzz", success ); 152 * GregorianCalendar cal(success); 153 * UDate currentTime_1 = cal.getTime(success); 154 * FieldPosition fp(0); 155 * UnicodeString dateString; 156 * formatter->format( currentTime_1, dateString, fp ); 157 * cout << "result: " << dateString << endl; 158 * 159 * // Parse the previous string back into a Date. 160 * ParsePosition pp(0); 161 * UDate currentTime_2 = formatter->parse(dateString, pp ); 162 * \endcode 163 * </pre> 164 * In the above example, the time value "currentTime_2" obtained from parsing 165 * will be equal to currentTime_1. However, they may not be equal if the am/pm 166 * marker 'a' is left out from the format pattern while the "hour in am/pm" 167 * pattern symbol is used. This information loss can happen when formatting the 168 * time in PM. 169 * 170 * <p> 171 * When parsing a date string using the abbreviated year pattern ("y" or "yy"), 172 * SimpleDateFormat must interpret the abbreviated year 173 * relative to some century. It does this by adjusting dates to be 174 * within 80 years before and 20 years after the time the SimpleDateFormat 175 * instance is created. For example, using a pattern of "MM/dd/yy" and a 176 * SimpleDateFormat instance created on Jan 1, 1997, the string 177 * "01/11/12" would be interpreted as Jan 11, 2012 while the string "05/04/64" 178 * would be interpreted as May 4, 1964. 179 * During parsing, only strings consisting of exactly two digits, as defined by 180 * <code>Unicode::isDigit()</code>, will be parsed into the default century. 181 * Any other numeric string, such as a one digit string, a three or more digit 182 * string, or a two digit string that isn't all digits (for example, "-1"), is 183 * interpreted literally. So "01/02/3" or "01/02/003" are parsed, using the 184 * same pattern, as Jan 2, 3 AD. Likewise, "01/02/-3" is parsed as Jan 2, 4 BC. 185 * 186 * <p> 187 * If the year pattern has more than two 'y' characters, the year is 188 * interpreted literally, regardless of the number of digits. So using the 189 * pattern "MM/dd/yyyy", "01/11/12" parses to Jan 11, 12 A.D. 190 * 191 * <p> 192 * When numeric fields abut one another directly, with no intervening delimiter 193 * characters, they constitute a run of abutting numeric fields. Such runs are 194 * parsed specially. For example, the format "HHmmss" parses the input text 195 * "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to 196 * parse "1234". In other words, the leftmost field of the run is flexible, 197 * while the others keep a fixed width. If the parse fails anywhere in the run, 198 * then the leftmost field is shortened by one character, and the entire run is 199 * parsed again. This is repeated until either the parse succeeds or the 200 * leftmost field is one character in length. If the parse still fails at that 201 * point, the parse of the run fails. 202 * 203 * <P> 204 * For time zones that have no names, SimpleDateFormat uses strings GMT+hours:minutes or 205 * GMT-hours:minutes. 206 * <P> 207 * The calendar defines what is the first day of the week, the first week of the 208 * year, whether hours are zero based or not (0 vs 12 or 24), and the timezone. 209 * There is one common number format to handle all the numbers; the digit count 210 * is handled programmatically according to the pattern. 211 * 212 * <p><em>User subclasses are not supported.</em> While clients may write 213 * subclasses, such code will not necessarily work and will not be 214 * guaranteed to work stably from release to release. 215 */ 216class U_I18N_API SimpleDateFormat: public DateFormat { 217public: 218 /** 219 * Construct a SimpleDateFormat using the default pattern for the default 220 * locale. 221 * <P> 222 * [Note:] Not all locales support SimpleDateFormat; for full generality, 223 * use the factory methods in the DateFormat class. 224 * @param status Output param set to success/failure code. 225 * @stable ICU 2.0 226 */ 227 SimpleDateFormat(UErrorCode& status); 228 229 /** 230 * Construct a SimpleDateFormat using the given pattern and the default locale. 231 * The locale is used to obtain the symbols used in formatting (e.g., the 232 * names of the months), but not to provide the pattern. 233 * <P> 234 * [Note:] Not all locales support SimpleDateFormat; for full generality, 235 * use the factory methods in the DateFormat class. 236 * @param pattern the pattern for the format. 237 * @param status Output param set to success/failure code. 238 * @stable ICU 2.0 239 */ 240 SimpleDateFormat(const UnicodeString& pattern, 241 UErrorCode& status); 242 243 /** 244 * Construct a SimpleDateFormat using the given pattern, numbering system override, and the default locale. 245 * The locale is used to obtain the symbols used in formatting (e.g., the 246 * names of the months), but not to provide the pattern. 247 * <P> 248 * A numbering system override is a string containing either the name of a known numbering system, 249 * or a set of field and numbering system pairs that specify which fields are to be formattied with 250 * the alternate numbering system. For example, to specify that all numeric fields in the specified 251 * date or time pattern are to be rendered using Thai digits, simply specify the numbering system override 252 * as "thai". To specify that just the year portion of the date be formatted using Hebrew numbering, 253 * use the override string "y=hebrew". Numbering system overrides can be combined using a semi-colon 254 * character in the override string, such as "d=decimal;M=arabic;y=hebrew", etc. 255 * 256 * <P> 257 * [Note:] Not all locales support SimpleDateFormat; for full generality, 258 * use the factory methods in the DateFormat class. 259 * @param pattern the pattern for the format. 260 * @param override the override string. 261 * @param status Output param set to success/failure code. 262 * @stable ICU 4.2 263 */ 264 SimpleDateFormat(const UnicodeString& pattern, 265 const UnicodeString& override, 266 UErrorCode& status); 267 268 /** 269 * Construct a SimpleDateFormat using the given pattern and locale. 270 * The locale is used to obtain the symbols used in formatting (e.g., the 271 * names of the months), but not to provide the pattern. 272 * <P> 273 * [Note:] Not all locales support SimpleDateFormat; for full generality, 274 * use the factory methods in the DateFormat class. 275 * @param pattern the pattern for the format. 276 * @param locale the given locale. 277 * @param status Output param set to success/failure code. 278 * @stable ICU 2.0 279 */ 280 SimpleDateFormat(const UnicodeString& pattern, 281 const Locale& locale, 282 UErrorCode& status); 283 284 /** 285 * Construct a SimpleDateFormat using the given pattern, numbering system override, and locale. 286 * The locale is used to obtain the symbols used in formatting (e.g., the 287 * names of the months), but not to provide the pattern. 288 * <P> 289 * A numbering system override is a string containing either the name of a known numbering system, 290 * or a set of field and numbering system pairs that specify which fields are to be formattied with 291 * the alternate numbering system. For example, to specify that all numeric fields in the specified 292 * date or time pattern are to be rendered using Thai digits, simply specify the numbering system override 293 * as "thai". To specify that just the year portion of the date be formatted using Hebrew numbering, 294 * use the override string "y=hebrew". Numbering system overrides can be combined using a semi-colon 295 * character in the override string, such as "d=decimal;M=arabic;y=hebrew", etc. 296 * <P> 297 * [Note:] Not all locales support SimpleDateFormat; for full generality, 298 * use the factory methods in the DateFormat class. 299 * @param pattern the pattern for the format. 300 * @param override the numbering system override. 301 * @param locale the given locale. 302 * @param status Output param set to success/failure code. 303 * @stable ICU 4.2 304 */ 305 SimpleDateFormat(const UnicodeString& pattern, 306 const UnicodeString& override, 307 const Locale& locale, 308 UErrorCode& status); 309 310 /** 311 * Construct a SimpleDateFormat using the given pattern and locale-specific 312 * symbol data. The formatter takes ownership of the DateFormatSymbols object; 313 * the caller is no longer responsible for deleting it. 314 * @param pattern the given pattern for the format. 315 * @param formatDataToAdopt the symbols to be adopted. 316 * @param status Output param set to success/faulure code. 317 * @stable ICU 2.0 318 */ 319 SimpleDateFormat(const UnicodeString& pattern, 320 DateFormatSymbols* formatDataToAdopt, 321 UErrorCode& status); 322 323 /** 324 * Construct a SimpleDateFormat using the given pattern and locale-specific 325 * symbol data. The DateFormatSymbols object is NOT adopted; the caller 326 * remains responsible for deleting it. 327 * @param pattern the given pattern for the format. 328 * @param formatData the formatting symbols to be use. 329 * @param status Output param set to success/faulure code. 330 * @stable ICU 2.0 331 */ 332 SimpleDateFormat(const UnicodeString& pattern, 333 const DateFormatSymbols& formatData, 334 UErrorCode& status); 335 336 /** 337 * Copy constructor. 338 * @stable ICU 2.0 339 */ 340 SimpleDateFormat(const SimpleDateFormat&); 341 342 /** 343 * Assignment operator. 344 * @stable ICU 2.0 345 */ 346 SimpleDateFormat& operator=(const SimpleDateFormat&); 347 348 /** 349 * Destructor. 350 * @stable ICU 2.0 351 */ 352 virtual ~SimpleDateFormat(); 353 354 /** 355 * Clone this Format object polymorphically. The caller owns the result and 356 * should delete it when done. 357 * @return A copy of the object. 358 * @stable ICU 2.0 359 */ 360 virtual Format* clone(void) const; 361 362 /** 363 * Return true if the given Format objects are semantically equal. Objects 364 * of different subclasses are considered unequal. 365 * @param other the object to be compared with. 366 * @return true if the given Format objects are semantically equal. 367 * @stable ICU 2.0 368 */ 369 virtual UBool operator==(const Format& other) const; 370 371 372 using DateFormat::format; 373 374 /** 375 * Format a date or time, which is the standard millis since 24:00 GMT, Jan 376 * 1, 1970. Overrides DateFormat pure virtual method. 377 * <P> 378 * Example: using the US locale: "yyyy.MM.dd e 'at' HH:mm:ss zzz" ->> 379 * 1996.07.10 AD at 15:08:56 PDT 380 * 381 * @param cal Calendar set to the date and time to be formatted 382 * into a date/time string. 383 * @param appendTo Output parameter to receive result. 384 * Result is appended to existing contents. 385 * @param pos The formatting position. On input: an alignment field, 386 * if desired. On output: the offsets of the alignment field. 387 * @return Reference to 'appendTo' parameter. 388 * @stable ICU 2.1 389 */ 390 virtual UnicodeString& format( Calendar& cal, 391 UnicodeString& appendTo, 392 FieldPosition& pos) const; 393 394 /** 395 * Format a date or time, which is the standard millis since 24:00 GMT, Jan 396 * 1, 1970. Overrides DateFormat pure virtual method. 397 * <P> 398 * Example: using the US locale: "yyyy.MM.dd e 'at' HH:mm:ss zzz" ->> 399 * 1996.07.10 AD at 15:08:56 PDT 400 * 401 * @param cal Calendar set to the date and time to be formatted 402 * into a date/time string. 403 * @param appendTo Output parameter to receive result. 404 * Result is appended to existing contents. 405 * @param posIter On return, can be used to iterate over positions 406 * of fields generated by this format call. Field values 407 * are defined in UDateFormatField. 408 * @param status Input/output param set to success/failure code. 409 * @return Reference to 'appendTo' parameter. 410 * @stable ICU 4.4 411 */ 412 virtual UnicodeString& format( Calendar& cal, 413 UnicodeString& appendTo, 414 FieldPositionIterator* posIter, 415 UErrorCode& status) const; 416 417 /** 418 * Format a date or time, which is the standard millis since 24:00 GMT, Jan 419 * 1, 1970. Overrides DateFormat pure virtual method. 420 * <P> 421 * Example: using the US locale: "yyyy.MM.dd e 'at' HH:mm:ss zzz" ->> 422 * 1996.07.10 AD at 15:08:56 PDT 423 * 424 * @param obj A Formattable containing the date-time value to be formatted 425 * into a date-time string. If the type of the Formattable 426 * is a numeric type, it is treated as if it were an 427 * instance of Date. 428 * @param appendTo Output parameter to receive result. 429 * Result is appended to existing contents. 430 * @param pos The formatting position. On input: an alignment field, 431 * if desired. On output: the offsets of the alignment field. 432 * @param status Input/output param set to success/failure code. 433 * @return Reference to 'appendTo' parameter. 434 * @stable ICU 2.0 435 */ 436 virtual UnicodeString& format( const Formattable& obj, 437 UnicodeString& appendTo, 438 FieldPosition& pos, 439 UErrorCode& status) const; 440 441 /** 442 * Format a date or time, which is the standard millis since 24:00 GMT, Jan 443 * 1, 1970. Overrides DateFormat pure virtual method. 444 * <P> 445 * Example: using the US locale: "yyyy.MM.dd e 'at' HH:mm:ss zzz" ->> 446 * 1996.07.10 AD at 15:08:56 PDT 447 * 448 * @param obj A Formattable containing the date-time value to be formatted 449 * into a date-time string. If the type of the Formattable 450 * is a numeric type, it is treated as if it were an 451 * instance of Date. 452 * @param appendTo Output parameter to receive result. 453 * Result is appended to existing contents. 454 * @param posIter On return, can be used to iterate over positions 455 * of fields generated by this format call. Field values 456 * are defined in UDateFormatField. 457 * @param status Input/output param set to success/failure code. 458 * @return Reference to 'appendTo' parameter. 459 * @stable ICU 4.4 460 */ 461 virtual UnicodeString& format( const Formattable& obj, 462 UnicodeString& appendTo, 463 FieldPositionIterator* posIter, 464 UErrorCode& status) const; 465 466 /** 467 * Redeclared DateFormat method. 468 * @param date the Date value to be formatted. 469 * @param appendTo Output parameter to receive result. 470 * Result is appended to existing contents. 471 * @param fieldPosition The formatting position. On input: an alignment field, 472 * if desired. On output: the offsets of the alignment field. 473 * @return Reference to 'appendTo' parameter. 474 * @stable ICU 2.1 475 */ 476 UnicodeString& format(UDate date, 477 UnicodeString& appendTo, 478 FieldPosition& fieldPosition) const; 479 480 /** 481 * Redeclared DateFormat method. 482 * @param date the Date value to be formatted. 483 * @param appendTo Output parameter to receive result. 484 * Result is appended to existing contents. 485 * @param posIter On return, can be used to iterate over positions 486 * of fields generated by this format call. Field values 487 * are defined in UDateFormatField. 488 * @param status Input/output param set to success/failure code. 489 * @return Reference to 'appendTo' parameter. 490 * @stable ICU 4.4 491 */ 492 UnicodeString& format(UDate date, 493 UnicodeString& appendTo, 494 FieldPositionIterator* posIter, 495 UErrorCode& status) const; 496 497 /** 498 * Redeclared DateFormat method. 499 * @param obj Object to be formatted. 500 * @param appendTo Output parameter to receive result. 501 * Result is appended to existing contents. 502 * @param status Input/output success/failure code. 503 * @return Reference to 'appendTo' parameter. 504 * @stable ICU 2.0 505 */ 506 UnicodeString& format(const Formattable& obj, 507 UnicodeString& appendTo, 508 UErrorCode& status) const; 509 510 /** 511 * Redeclared DateFormat method. 512 * @param date Date value to be formatted. 513 * @param appendTo Output parameter to receive result. 514 * Result is appended to existing contents. 515 * @return Reference to 'appendTo' parameter. 516 * @stable ICU 2.0 517 */ 518 UnicodeString& format(UDate date, UnicodeString& appendTo) const; 519 520 /** 521 * Parse a date/time string beginning at the given parse position. For 522 * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date 523 * that is equivalent to Date(837039928046). 524 * <P> 525 * By default, parsing is lenient: If the input is not in the form used by 526 * this object's format method but can still be parsed as a date, then the 527 * parse succeeds. Clients may insist on strict adherence to the format by 528 * calling setLenient(false). 529 * 530 * @param text The date/time string to be parsed 531 * @param cal a Calendar set to the date and time to be formatted 532 * into a date/time string. 533 * @param pos On input, the position at which to start parsing; on 534 * output, the position at which parsing terminated, or the 535 * start position if the parse failed. 536 * @return A valid UDate if the input could be parsed. 537 * @stable ICU 2.1 538 */ 539 virtual void parse( const UnicodeString& text, 540 Calendar& cal, 541 ParsePosition& pos) const; 542 543 /** 544 * Parse a date/time string starting at the given parse position. For 545 * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date 546 * that is equivalent to Date(837039928046). 547 * <P> 548 * By default, parsing is lenient: If the input is not in the form used by 549 * this object's format method but can still be parsed as a date, then the 550 * parse succeeds. Clients may insist on strict adherence to the format by 551 * calling setLenient(false). 552 * 553 * @see DateFormat::setLenient(boolean) 554 * 555 * @param text The date/time string to be parsed 556 * @param pos On input, the position at which to start parsing; on 557 * output, the position at which parsing terminated, or the 558 * start position if the parse failed. 559 * @return A valid UDate if the input could be parsed. 560 * @stable ICU 2.0 561 */ 562 UDate parse( const UnicodeString& text, 563 ParsePosition& pos) const; 564 565 566 /** 567 * Parse a date/time string. For example, a time text "07/10/96 4:5 PM, PDT" 568 * will be parsed into a UDate that is equivalent to Date(837039928046). 569 * Parsing begins at the beginning of the string and proceeds as far as 570 * possible. Assuming no parse errors were encountered, this function 571 * doesn't return any information about how much of the string was consumed 572 * by the parsing. If you need that information, use the version of 573 * parse() that takes a ParsePosition. 574 * 575 * @param text The date/time string to be parsed 576 * @param status Filled in with U_ZERO_ERROR if the parse was successful, and with 577 * an error value if there was a parse error. 578 * @return A valid UDate if the input could be parsed. 579 * @stable ICU 2.0 580 */ 581 virtual UDate parse( const UnicodeString& text, 582 UErrorCode& status) const; 583 584 /** 585 * Set the start UDate used to interpret two-digit year strings. 586 * When dates are parsed having 2-digit year strings, they are placed within 587 * a assumed range of 100 years starting on the two digit start date. For 588 * example, the string "24-Jan-17" may be in the year 1817, 1917, 2017, or 589 * some other year. SimpleDateFormat chooses a year so that the resultant 590 * date is on or after the two digit start date and within 100 years of the 591 * two digit start date. 592 * <P> 593 * By default, the two digit start date is set to 80 years before the current 594 * time at which a SimpleDateFormat object is created. 595 * @param d start UDate used to interpret two-digit year strings. 596 * @param status Filled in with U_ZERO_ERROR if the parse was successful, and with 597 * an error value if there was a parse error. 598 * @stable ICU 2.0 599 */ 600 virtual void set2DigitYearStart(UDate d, UErrorCode& status); 601 602 /** 603 * Get the start UDate used to interpret two-digit year strings. 604 * When dates are parsed having 2-digit year strings, they are placed within 605 * a assumed range of 100 years starting on the two digit start date. For 606 * example, the string "24-Jan-17" may be in the year 1817, 1917, 2017, or 607 * some other year. SimpleDateFormat chooses a year so that the resultant 608 * date is on or after the two digit start date and within 100 years of the 609 * two digit start date. 610 * <P> 611 * By default, the two digit start date is set to 80 years before the current 612 * time at which a SimpleDateFormat object is created. 613 * @param status Filled in with U_ZERO_ERROR if the parse was successful, and with 614 * an error value if there was a parse error. 615 * @stable ICU 2.0 616 */ 617 UDate get2DigitYearStart(UErrorCode& status) const; 618 619 /** 620 * Return a pattern string describing this date format. 621 * @param result Output param to receive the pattern. 622 * @return A reference to 'result'. 623 * @stable ICU 2.0 624 */ 625 virtual UnicodeString& toPattern(UnicodeString& result) const; 626 627 /** 628 * Return a localized pattern string describing this date format. 629 * In most cases, this will return the same thing as toPattern(), 630 * but a locale can specify characters to use in pattern descriptions 631 * in place of the ones described in this class's class documentation. 632 * (Presumably, letters that would be more mnemonic in that locale's 633 * language.) This function would produce a pattern using those 634 * letters. 635 * 636 * @param result Receives the localized pattern. 637 * @param status Output param set to success/failure code on 638 * exit. If the pattern is invalid, this will be 639 * set to a failure result. 640 * @return A reference to 'result'. 641 * @stable ICU 2.0 642 */ 643 virtual UnicodeString& toLocalizedPattern(UnicodeString& result, 644 UErrorCode& status) const; 645 646 /** 647 * Apply the given unlocalized pattern string to this date format. 648 * (i.e., after this call, this formatter will format dates according to 649 * the new pattern) 650 * 651 * @param pattern The pattern to be applied. 652 * @stable ICU 2.0 653 */ 654 virtual void applyPattern(const UnicodeString& pattern); 655 656 /** 657 * Apply the given localized pattern string to this date format. 658 * (see toLocalizedPattern() for more information on localized patterns.) 659 * 660 * @param pattern The localized pattern to be applied. 661 * @param status Output param set to success/failure code on 662 * exit. If the pattern is invalid, this will be 663 * set to a failure result. 664 * @stable ICU 2.0 665 */ 666 virtual void applyLocalizedPattern(const UnicodeString& pattern, 667 UErrorCode& status); 668 669 /** 670 * Gets the date/time formatting symbols (this is an object carrying 671 * the various strings and other symbols used in formatting: e.g., month 672 * names and abbreviations, time zone names, AM/PM strings, etc.) 673 * @return a copy of the date-time formatting data associated 674 * with this date-time formatter. 675 * @stable ICU 2.0 676 */ 677 virtual const DateFormatSymbols* getDateFormatSymbols(void) const; 678 679 /** 680 * Set the date/time formatting symbols. The caller no longer owns the 681 * DateFormatSymbols object and should not delete it after making this call. 682 * @param newFormatSymbols the given date-time formatting symbols to copy. 683 * @stable ICU 2.0 684 */ 685 virtual void adoptDateFormatSymbols(DateFormatSymbols* newFormatSymbols); 686 687 /** 688 * Set the date/time formatting data. 689 * @param newFormatSymbols the given date-time formatting symbols to copy. 690 * @stable ICU 2.0 691 */ 692 virtual void setDateFormatSymbols(const DateFormatSymbols& newFormatSymbols); 693 694 /** 695 * Return the class ID for this class. This is useful only for comparing to 696 * a return value from getDynamicClassID(). For example: 697 * <pre> 698 * . Base* polymorphic_pointer = createPolymorphicObject(); 699 * . if (polymorphic_pointer->getDynamicClassID() == 700 * . erived::getStaticClassID()) ... 701 * </pre> 702 * @return The class ID for all objects of this class. 703 * @stable ICU 2.0 704 */ 705 static UClassID U_EXPORT2 getStaticClassID(void); 706 707 /** 708 * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This 709 * method is to implement a simple version of RTTI, since not all C++ 710 * compilers support genuine RTTI. Polymorphic operator==() and clone() 711 * methods call this method. 712 * 713 * @return The class ID for this object. All objects of a 714 * given class have the same class ID. Objects of 715 * other classes have different class IDs. 716 * @stable ICU 2.0 717 */ 718 virtual UClassID getDynamicClassID(void) const; 719 720 /** 721 * Set the calendar to be used by this date format. Initially, the default 722 * calendar for the specified or default locale is used. The caller should 723 * not delete the Calendar object after it is adopted by this call. 724 * Adopting a new calendar will change to the default symbols. 725 * 726 * @param calendarToAdopt Calendar object to be adopted. 727 * @stable ICU 2.0 728 */ 729 virtual void adoptCalendar(Calendar* calendarToAdopt); 730 731 /** 732 * This is for ICU internal use only. Please do not use. 733 * Check whether the 'field' is smaller than all the fields covered in 734 * pattern, return TRUE if it is. The sequence of calendar field, 735 * from large to small is: ERA, YEAR, MONTH, DATE, AM_PM, HOUR, MINUTE,... 736 * @param field the calendar field need to check against 737 * @return TRUE if the 'field' is smaller than all the fields 738 * covered in pattern. FALSE otherwise. 739 * @internal ICU 4.0 740 */ 741 UBool isFieldUnitIgnored(UCalendarDateFields field) const; 742 743 744 /** 745 * This is for ICU internal use only. Please do not use. 746 * Check whether the 'field' is smaller than all the fields covered in 747 * pattern, return TRUE if it is. The sequence of calendar field, 748 * from large to small is: ERA, YEAR, MONTH, DATE, AM_PM, HOUR, MINUTE,... 749 * @param pattern the pattern to check against 750 * @param field the calendar field need to check against 751 * @return TRUE if the 'field' is smaller than all the fields 752 * covered in pattern. FALSE otherwise. 753 * @internal ICU 4.0 754 */ 755 static UBool isFieldUnitIgnored(const UnicodeString& pattern, 756 UCalendarDateFields field); 757 758 759 760 /** 761 * This is for ICU internal use only. Please do not use. 762 * Get the locale of this simple date formatter. 763 * It is used in DateIntervalFormat. 764 * 765 * @return locale in this simple date formatter 766 * @internal ICU 4.0 767 */ 768 const Locale& getSmpFmtLocale(void) const; 769 770 771private: 772 friend class DateFormat; 773 774 void initializeDefaultCentury(void); 775 776 SimpleDateFormat(); // default constructor not implemented 777 778 /** 779 * Used by the DateFormat factory methods to construct a SimpleDateFormat. 780 * @param timeStyle the time style. 781 * @param dateStyle the date style. 782 * @param locale the given locale. 783 * @param status Output param set to success/failure code on 784 * exit. 785 */ 786 SimpleDateFormat(EStyle timeStyle, EStyle dateStyle, const Locale& locale, UErrorCode& status); 787 788 /** 789 * Construct a SimpleDateFormat for the given locale. If no resource data 790 * is available, create an object of last resort, using hard-coded strings. 791 * This is an internal method, called by DateFormat. It should never fail. 792 * @param locale the given locale. 793 * @param status Output param set to success/failure code on 794 * exit. 795 */ 796 SimpleDateFormat(const Locale& locale, UErrorCode& status); // Use default pattern 797 798 /** 799 * Hook called by format(... FieldPosition& ...) and format(...FieldPositionIterator&...) 800 */ 801 UnicodeString& _format(Calendar& cal, UnicodeString& appendTo, FieldPositionHandler& handler, 802 UErrorCode& status) const; 803 804 /** 805 * Called by format() to format a single field. 806 * 807 * @param appendTo Output parameter to receive result. 808 * Result is appended to existing contents. 809 * @param ch The format character we encountered in the pattern. 810 * @param count Number of characters in the current pattern symbol (e.g., 811 * "yyyy" in the pattern would result in a call to this function 812 * with ch equal to 'y' and count equal to 4) 813 * @param handler Records information about field positions. 814 * @param cal Calendar to use 815 * @param status Receives a status code, which will be U_ZERO_ERROR if the operation 816 * succeeds. 817 */ 818 void subFormat(UnicodeString &appendTo, 819 UChar ch, 820 int32_t count, 821 FieldPositionHandler& handler, 822 Calendar& cal, 823 UErrorCode& status) const; // in case of illegal argument 824 825 /** 826 * Used by subFormat() to format a numeric value. 827 * Appends to toAppendTo a string representation of "value" 828 * having a number of digits between "minDigits" and 829 * "maxDigits". Uses the DateFormat's NumberFormat. 830 * 831 * @param currentNumberFormat 832 * @param appendTo Output parameter to receive result. 833 * Formatted number is appended to existing contents. 834 * @param value Value to format. 835 * @param minDigits Minimum number of digits the result should have 836 * @param maxDigits Maximum number of digits the result should have 837 */ 838 void zeroPaddingNumber(NumberFormat *currentNumberFormat, 839 UnicodeString &appendTo, 840 int32_t value, 841 int32_t minDigits, 842 int32_t maxDigits) const; 843 844 /** 845 * Return true if the given format character, occuring count 846 * times, represents a numeric field. 847 */ 848 static UBool isNumeric(UChar formatChar, int32_t count); 849 850 /** 851 * initializes fCalendar from parameters. Returns fCalendar as a convenience. 852 * @param adoptZone Zone to be adopted, or NULL for TimeZone::createDefault(). 853 * @param locale Locale of the calendar 854 * @param status Error code 855 * @return the newly constructed fCalendar 856 */ 857 Calendar *initializeCalendar(TimeZone* adoptZone, const Locale& locale, UErrorCode& status); 858 859 /** 860 * initializes fSymbols from parameters. 861 * @param locale Locale of the symbols 862 * @param calendar Alias to Calendar that will be used. 863 * @param status Error code 864 */ 865 void initializeSymbols(const Locale& locale, Calendar* calendar, UErrorCode& status); 866 867 /** 868 * Called by several of the constructors to load pattern data and formatting symbols 869 * out of a resource bundle and initialize the locale based on it. 870 * @param timeStyle The time style, as passed to DateFormat::createDateInstance(). 871 * @param dateStyle The date style, as passed to DateFormat::createTimeInstance(). 872 * @param locale The locale to load the patterns from. 873 * @param status Filled in with an error code if loading the data from the 874 * resources fails. 875 */ 876 void construct(EStyle timeStyle, EStyle dateStyle, const Locale& locale, UErrorCode& status); 877 878 /** 879 * Called by construct() and the various constructors to set up the SimpleDateFormat's 880 * Calendar and NumberFormat objects. 881 * @param locale The locale for which we want a Calendar and a NumberFormat. 882 * @param status Filled in with an error code if creating either subobject fails. 883 */ 884 void initialize(const Locale& locale, UErrorCode& status); 885 886 /** 887 * Private code-size reduction function used by subParse. 888 * @param text the time text being parsed. 889 * @param start where to start parsing. 890 * @param field the date field being parsed. 891 * @param stringArray the string array to parsed. 892 * @param stringArrayCount the size of the array. 893 * @param cal a Calendar set to the date and time to be formatted 894 * into a date/time string. 895 * @return the new start position if matching succeeded; a negative number 896 * indicating matching failure, otherwise. 897 */ 898 int32_t matchString(const UnicodeString& text, int32_t start, UCalendarDateFields field, 899 const UnicodeString* stringArray, int32_t stringArrayCount, Calendar& cal) const; 900 901 /** 902 * Private code-size reduction function used by subParse. 903 * @param text the time text being parsed. 904 * @param start where to start parsing. 905 * @param field the date field being parsed. 906 * @param stringArray the string array to parsed. 907 * @param stringArrayCount the size of the array. 908 * @param cal a Calendar set to the date and time to be formatted 909 * into a date/time string. 910 * @return the new start position if matching succeeded; a negative number 911 * indicating matching failure, otherwise. 912 */ 913 int32_t matchQuarterString(const UnicodeString& text, int32_t start, UCalendarDateFields field, 914 const UnicodeString* stringArray, int32_t stringArrayCount, Calendar& cal) const; 915 916 /** 917 * Private function used by subParse to match literal pattern text. 918 * 919 * @param pattern the pattern string 920 * @param patternOffset the starting offset into the pattern text. On 921 * outupt will be set the offset of the first non-literal character in the pattern 922 * @param text the text being parsed 923 * @param textOffset the starting offset into the text. On output 924 * will be set to the offset of the character after the match 925 * @param lenient <code>TRUE</code> if the parse is lenient, <code>FALSE</code> otherwise. 926 * 927 * @return <code>TRUE</code> if the literal text could be matched, <code>FALSE</code> otherwise. 928 */ 929 static UBool matchLiterals(const UnicodeString &pattern, int32_t &patternOffset, 930 const UnicodeString &text, int32_t &textOffset, UBool lenient); 931 932 /** 933 * Private member function that converts the parsed date strings into 934 * timeFields. Returns -start (for ParsePosition) if failed. 935 * @param text the time text to be parsed. 936 * @param start where to start parsing. 937 * @param ch the pattern character for the date field text to be parsed. 938 * @param count the count of a pattern character. 939 * @param obeyCount if true then the count is strictly obeyed. 940 * @param allowNegative 941 * @param ambiguousYear If true then the two-digit year == the default start year. 942 * @param saveHebrewMonth Used to hang onto month until year is known. 943 * @param cal a Calendar set to the date and time to be formatted 944 * into a date/time string. 945 * @param patLoc 946 * @return the new start position if matching succeeded; a negative number 947 * indicating matching failure, otherwise. 948 */ 949 int32_t subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count, 950 UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal, 951 int32_t patLoc) const; 952 953 void parseInt(const UnicodeString& text, 954 Formattable& number, 955 ParsePosition& pos, 956 UBool allowNegative, 957 NumberFormat *fmt) const; 958 959 void parseInt(const UnicodeString& text, 960 Formattable& number, 961 int32_t maxDigits, 962 ParsePosition& pos, 963 UBool allowNegative, 964 NumberFormat *fmt) const; 965 966 int32_t checkIntSuffix(const UnicodeString& text, int32_t start, 967 int32_t patLoc, UBool isNegative) const; 968 969 /** 970 * Translate a pattern, mapping each character in the from string to the 971 * corresponding character in the to string. Return an error if the original 972 * pattern contains an unmapped character, or if a quote is unmatched. 973 * Quoted (single quotes only) material is not translated. 974 * @param originalPattern the original pattern. 975 * @param translatedPattern Output param to receive the translited pattern. 976 * @param from the characters to be translited from. 977 * @param to the characters to be translited to. 978 * @param status Receives a status code, which will be U_ZERO_ERROR 979 * if the operation succeeds. 980 */ 981 static void translatePattern(const UnicodeString& originalPattern, 982 UnicodeString& translatedPattern, 983 const UnicodeString& from, 984 const UnicodeString& to, 985 UErrorCode& status); 986 987 /** 988 * Sets the starting date of the 100-year window that dates with 2-digit years 989 * are considered to fall within. 990 * @param startDate the start date 991 * @param status Receives a status code, which will be U_ZERO_ERROR 992 * if the operation succeeds. 993 */ 994 void parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& status); 995 996 /** 997 * Return the length matched by the given affix, or -1 if none. 998 * Runs of white space in the affix, match runs of white space in 999 * the input. 1000 * @param affix pattern string, taken as a literal 1001 * @param input input text 1002 * @param pos offset into input at which to begin matching 1003 * @return length of input that matches, or -1 if match failure 1004 */ 1005 int32_t compareSimpleAffix(const UnicodeString& affix, 1006 const UnicodeString& input, 1007 int32_t pos) const; 1008 1009 /** 1010 * Skip over a run of zero or more Pattern_White_Space characters at 1011 * pos in text. 1012 */ 1013 int32_t skipPatternWhiteSpace(const UnicodeString& text, int32_t pos) const; 1014 1015 /** 1016 * Skip over a run of zero or more isUWhiteSpace() characters at pos 1017 * in text. 1018 */ 1019 int32_t skipUWhiteSpace(const UnicodeString& text, int32_t pos) const; 1020 1021 /** 1022 * Private methods for formatting/parsing GMT string 1023 */ 1024 void appendGMT(NumberFormat *currentNumberFormat,UnicodeString &appendTo, Calendar& cal, UErrorCode& status) const; 1025 void formatGMTDefault(NumberFormat *currentNumberFormat,UnicodeString &appendTo, int32_t offset) const; 1026 int32_t parseGMT(const UnicodeString &text, ParsePosition &pos) const; 1027 int32_t parseGMTDefault(const UnicodeString &text, ParsePosition &pos) const; 1028 UBool isDefaultGMTFormat() const; 1029 1030 void formatRFC822TZ(UnicodeString &appendTo, int32_t offset) const; 1031 1032 /** 1033 * Initialize MessageFormat instances used for GMT formatting/parsing 1034 */ 1035 void initGMTFormatters(UErrorCode &status); 1036 1037 /** 1038 * Initialize NumberFormat instances used for numbering system overrides. 1039 */ 1040 void initNumberFormatters(const Locale &locale,UErrorCode &status); 1041 1042 /** 1043 * Get the numbering system to be used for a particular field. 1044 */ 1045 NumberFormat * getNumberFormatByIndex(UDateFormatField index) const; 1046 1047 /** 1048 * Parse the given override string and set up structures for number formats 1049 */ 1050 void processOverrideString(const Locale &locale, const UnicodeString &str, int8_t type, UErrorCode &status); 1051 1052 /** 1053 * Used to map pattern characters to Calendar field identifiers. 1054 */ 1055 static const UCalendarDateFields fgPatternIndexToCalendarField[]; 1056 1057 /** 1058 * Map index into pattern character string to DateFormat field number 1059 */ 1060 static const UDateFormatField fgPatternIndexToDateFormatField[]; 1061 1062 /** 1063 * Lazy TimeZoneFormat instantiation, semantically const 1064 */ 1065 TimeZoneFormat *tzFormat() const; 1066 1067 /** 1068 * Used to map Calendar field to field level. 1069 * The larger the level, the smaller the field unit. 1070 * For example, UCAL_ERA level is 0, UCAL_YEAR level is 10, 1071 * UCAL_MONTH level is 20. 1072 */ 1073 static const int32_t fgCalendarFieldToLevel[]; 1074 static const int32_t fgPatternCharToLevel[]; 1075 1076 /** 1077 * The formatting pattern for this formatter. 1078 */ 1079 UnicodeString fPattern; 1080 1081 /** 1082 * The numbering system override for dates. 1083 */ 1084 UnicodeString fDateOverride; 1085 1086 /** 1087 * The numbering system override for times. 1088 */ 1089 UnicodeString fTimeOverride; 1090 1091 1092 /** 1093 * The original locale used (for reloading symbols) 1094 */ 1095 Locale fLocale; 1096 1097 /** 1098 * A pointer to an object containing the strings to use in formatting (e.g., 1099 * month and day names, AM and PM strings, time zone names, etc.) 1100 */ 1101 DateFormatSymbols* fSymbols; // Owned 1102 1103 /** 1104 * The time zone formatter 1105 */ 1106 TimeZoneFormat* fTimeZoneFormat; 1107 1108 /** 1109 * If dates have ambiguous years, we map them into the century starting 1110 * at defaultCenturyStart, which may be any date. If defaultCenturyStart is 1111 * set to SYSTEM_DEFAULT_CENTURY, which it is by default, then the system 1112 * values are used. The instance values defaultCenturyStart and 1113 * defaultCenturyStartYear are only used if explicitly set by the user 1114 * through the API method parseAmbiguousDatesAsAfter(). 1115 */ 1116 UDate fDefaultCenturyStart; 1117 1118 /** 1119 * See documentation for defaultCenturyStart. 1120 */ 1121 /*transient*/ int32_t fDefaultCenturyStartYear; 1122 1123 enum ParsedTZType { 1124 TZTYPE_UNK, 1125 TZTYPE_STD, 1126 TZTYPE_DST 1127 }; 1128 1129 ParsedTZType tztype; // here to avoid api change 1130 1131 typedef struct NSOverride { 1132 NumberFormat *nf; 1133 int32_t hash; 1134 NSOverride *next; 1135 } NSOverride; 1136 1137 /* 1138 * MessageFormat instances used for localized GMT format 1139 */ 1140 enum { 1141 kGMTNegativeHMS = 0, 1142 kGMTNegativeHM, 1143 kGMTPositiveHMS, 1144 kGMTPositiveHM, 1145 1146 kNumGMTFormatters 1147 }; 1148 enum { 1149 kGMTNegativeHMSMinLenIdx = 0, 1150 kGMTPositiveHMSMinLenIdx, 1151 1152 kNumGMTFormatMinLengths 1153 }; 1154 1155 MessageFormat **fGMTFormatters; 1156 // If a GMT hour format has a second field, we need to make sure 1157 // the length of input localized GMT string must match the expected 1158 // length. Otherwise, sub DateForamt handling offset format may 1159 // unexpectedly success parsing input GMT string without second field. 1160 // See #6880 about this issue. 1161 // TODO: SimpleDateFormat should provide an option to invalidate 1162 // 1163 int32_t fGMTFormatHmsMinLen[kNumGMTFormatMinLengths]; 1164 1165 NumberFormat **fNumberFormatters; 1166 1167 NSOverride *fOverrideList; 1168 1169 UBool fHaveDefaultCentury; 1170}; 1171 1172inline UDate 1173SimpleDateFormat::get2DigitYearStart(UErrorCode& /*status*/) const 1174{ 1175 return fDefaultCenturyStart; 1176} 1177 1178inline UnicodeString& 1179SimpleDateFormat::format(const Formattable& obj, 1180 UnicodeString& appendTo, 1181 UErrorCode& status) const { 1182 // Don't use Format:: - use immediate base class only, 1183 // in case immediate base modifies behavior later. 1184 return DateFormat::format(obj, appendTo, status); 1185} 1186 1187inline UnicodeString& 1188SimpleDateFormat::format(const Formattable& obj, 1189 UnicodeString& appendTo, 1190 FieldPosition& pos, 1191 UErrorCode& status) const 1192{ 1193 // Don't use Format:: - use immediate base class only, 1194 // in case immediate base modifies behavior later. 1195 return DateFormat::format(obj, appendTo, pos, status); 1196} 1197 1198inline UnicodeString& 1199SimpleDateFormat::format(const Formattable& obj, 1200 UnicodeString& appendTo, 1201 FieldPositionIterator* posIter, 1202 UErrorCode& status) const 1203{ 1204 // Don't use Format:: - use immediate base class only, 1205 // in case immediate base modifies behavior later. 1206 return DateFormat::format(obj, appendTo, posIter, status); 1207} 1208 1209inline UnicodeString& 1210SimpleDateFormat::format(UDate date, 1211 UnicodeString& appendTo, 1212 FieldPosition& fieldPosition) const { 1213 // Don't use Format:: - use immediate base class only, 1214 // in case immediate base modifies behavior later. 1215 return DateFormat::format(date, appendTo, fieldPosition); 1216} 1217 1218inline UnicodeString& 1219SimpleDateFormat::format(UDate date, 1220 UnicodeString& appendTo, 1221 FieldPositionIterator* posIter, 1222 UErrorCode& status) const { 1223 // Don't use Format:: - use immediate base class only, 1224 // in case immediate base modifies behavior later. 1225 return DateFormat::format(date, appendTo, posIter, status); 1226} 1227 1228inline UnicodeString& 1229SimpleDateFormat::format(UDate date, UnicodeString& appendTo) const { 1230 return DateFormat::format(date, appendTo); 1231} 1232 1233U_NAMESPACE_END 1234 1235#endif /* #if !UCONFIG_NO_FORMATTING */ 1236 1237#endif // _SMPDTFMT 1238//eof 1239