dtitvfmt.h 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044
  1. /********************************************************************************
  2. * Copyright (C) 2008-2016, International Business Machines Corporation and
  3. * others. All Rights Reserved.
  4. *******************************************************************************
  5. *
  6. * File DTITVFMT.H
  7. *
  8. *******************************************************************************
  9. */
  10. #ifndef __DTITVFMT_H__
  11. #define __DTITVFMT_H__
  12. #include "unicode/utypes.h"
  13. /**
  14. * \file
  15. * \brief C++ API: Format and parse date interval in a language-independent manner.
  16. */
  17. #if !UCONFIG_NO_FORMATTING
  18. #include "unicode/ucal.h"
  19. #include "unicode/smpdtfmt.h"
  20. #include "unicode/dtintrv.h"
  21. #include "unicode/dtitvinf.h"
  22. #include "unicode/dtptngen.h"
  23. U_NAMESPACE_BEGIN
  24. /**
  25. * DateIntervalFormat is a class for formatting and parsing date
  26. * intervals in a language-independent manner.
  27. * Only formatting is supported, parsing is not supported.
  28. *
  29. * <P>
  30. * Date interval means from one date to another date,
  31. * for example, from "Jan 11, 2008" to "Jan 18, 2008".
  32. * We introduced class DateInterval to represent it.
  33. * DateInterval is a pair of UDate, which is
  34. * the standard milliseconds since 24:00 GMT, Jan 1, 1970.
  35. *
  36. * <P>
  37. * DateIntervalFormat formats a DateInterval into
  38. * text as compactly as possible.
  39. * For example, the date interval format from "Jan 11, 2008" to "Jan 18,. 2008"
  40. * is "Jan 11-18, 2008" for English.
  41. * And it parses text into DateInterval,
  42. * although initially, parsing is not supported.
  43. *
  44. * <P>
  45. * There is no structural information in date time patterns.
  46. * For any punctuations and string literals inside a date time pattern,
  47. * we do not know whether it is just a separator, or a prefix, or a suffix.
  48. * Without such information, so, it is difficult to generate a sub-pattern
  49. * (or super-pattern) by algorithm.
  50. * So, formatting a DateInterval is pattern-driven. It is very
  51. * similar to formatting in SimpleDateFormat.
  52. * We introduce class DateIntervalInfo to save date interval
  53. * patterns, similar to date time pattern in SimpleDateFormat.
  54. *
  55. * <P>
  56. * Logically, the interval patterns are mappings
  57. * from (skeleton, the_largest_different_calendar_field)
  58. * to (date_interval_pattern).
  59. *
  60. * <P>
  61. * A skeleton
  62. * <ol>
  63. * <li>
  64. * only keeps the field pattern letter and ignores all other parts
  65. * in a pattern, such as space, punctuations, and string literals.
  66. * </li>
  67. * <li>
  68. * hides the order of fields.
  69. * </li>
  70. * <li>
  71. * might hide a field's pattern letter length.
  72. * </li>
  73. * </ol>
  74. *
  75. * For those non-digit calendar fields, the pattern letter length is
  76. * important, such as MMM, MMMM, and MMMMM; EEE and EEEE,
  77. * and the field's pattern letter length is honored.
  78. *
  79. * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy,
  80. * the field pattern length is ignored and the best match, which is defined
  81. * in date time patterns, will be returned without honor the field pattern
  82. * letter length in skeleton.
  83. *
  84. * <P>
  85. * The calendar fields we support for interval formatting are:
  86. * year, month, date, day-of-week, am-pm, hour, hour-of-day, minute, and second
  87. * (though we do not currently have specific intervalFormat date for skeletons
  88. * with seconds).
  89. * Those calendar fields can be defined in the following order:
  90. * year > month > date > hour (in day) > minute > second
  91. *
  92. * The largest different calendar fields between 2 calendars is the
  93. * first different calendar field in above order.
  94. *
  95. * For example: the largest different calendar fields between "Jan 10, 2007"
  96. * and "Feb 20, 2008" is year.
  97. *
  98. * <P>
  99. * For other calendar fields, the compact interval formatting is not
  100. * supported. And the interval format will be fall back to fall-back
  101. * patterns, which is mostly "{date0} - {date1}".
  102. *
  103. * <P>
  104. * There is a set of pre-defined static skeleton strings.
  105. * There are pre-defined interval patterns for those pre-defined skeletons
  106. * in locales' resource files.
  107. * For example, for a skeleton UDAT_YEAR_ABBR_MONTH_DAY, which is &quot;yMMMd&quot;,
  108. * in en_US, if the largest different calendar field between date1 and date2
  109. * is &quot;year&quot;, the date interval pattern is &quot;MMM d, yyyy - MMM d, yyyy&quot;,
  110. * such as &quot;Jan 10, 2007 - Jan 10, 2008&quot;.
  111. * If the largest different calendar field between date1 and date2 is &quot;month&quot;,
  112. * the date interval pattern is &quot;MMM d - MMM d, yyyy&quot;,
  113. * such as &quot;Jan 10 - Feb 10, 2007&quot;.
  114. * If the largest different calendar field between date1 and date2 is &quot;day&quot;,
  115. * the date interval pattern is &quot;MMM d-d, yyyy&quot;, such as &quot;Jan 10-20, 2007&quot;.
  116. *
  117. * For date skeleton, the interval patterns when year, or month, or date is
  118. * different are defined in resource files.
  119. * For time skeleton, the interval patterns when am/pm, or hour, or minute is
  120. * different are defined in resource files.
  121. *
  122. * <P>
  123. * If a skeleton is not found in a locale's DateIntervalInfo, which means
  124. * the interval patterns for the skeleton is not defined in resource file,
  125. * the interval pattern will falls back to the interval "fallback" pattern
  126. * defined in resource file.
  127. * If the interval "fallback" pattern is not defined, the default fall-back
  128. * is "{date0} - {data1}".
  129. *
  130. * <P>
  131. * For the combination of date and time,
  132. * The rule to generate interval patterns are:
  133. * <ol>
  134. * <li>
  135. * when the year, month, or day differs, falls back to fall-back
  136. * interval pattern, which mostly is the concatenate the two original
  137. * expressions with a separator between,
  138. * For example, interval pattern from "Jan 10, 2007 10:10 am"
  139. * to "Jan 11, 2007 10:10am" is
  140. * "Jan 10, 2007 10:10 am - Jan 11, 2007 10:10am"
  141. * </li>
  142. * <li>
  143. * otherwise, present the date followed by the range expression
  144. * for the time.
  145. * For example, interval pattern from "Jan 10, 2007 10:10 am"
  146. * to "Jan 10, 2007 11:10am" is "Jan 10, 2007 10:10 am - 11:10am"
  147. * </li>
  148. * </ol>
  149. *
  150. *
  151. * <P>
  152. * If two dates are the same, the interval pattern is the single date pattern.
  153. * For example, interval pattern from "Jan 10, 2007" to "Jan 10, 2007" is
  154. * "Jan 10, 2007".
  155. *
  156. * Or if the presenting fields between 2 dates have the exact same values,
  157. * the interval pattern is the single date pattern.
  158. * For example, if user only requests year and month,
  159. * the interval pattern from "Jan 10, 2007" to "Jan 20, 2007" is "Jan 2007".
  160. *
  161. * <P>
  162. * DateIntervalFormat needs the following information for correct
  163. * formatting: time zone, calendar type, pattern, date format symbols,
  164. * and date interval patterns.
  165. * It can be instantiated in 2 ways:
  166. * <ol>
  167. * <li>
  168. * create an instance using default or given locale plus given skeleton.
  169. * Users are encouraged to created date interval formatter this way and
  170. * to use the pre-defined skeleton macros, such as
  171. * UDAT_YEAR_NUM_MONTH, which consists the calendar fields and
  172. * the format style.
  173. * </li>
  174. * <li>
  175. * create an instance using default or given locale plus given skeleton
  176. * plus a given DateIntervalInfo.
  177. * This factory method is for powerful users who want to provide their own
  178. * interval patterns.
  179. * Locale provides the timezone, calendar, and format symbols information.
  180. * Local plus skeleton provides full pattern information.
  181. * DateIntervalInfo provides the date interval patterns.
  182. * </li>
  183. * </ol>
  184. *
  185. * <P>
  186. * For the calendar field pattern letter, such as G, y, M, d, a, h, H, m, s etc.
  187. * DateIntervalFormat uses the same syntax as that of
  188. * DateTime format.
  189. *
  190. * <P>
  191. * Code Sample: general usage
  192. * <pre>
  193. * \code
  194. * // the date interval object which the DateIntervalFormat formats on
  195. * // and parses into
  196. * DateInterval* dtInterval = new DateInterval(1000*3600*24, 1000*3600*24*2);
  197. * UErrorCode status = U_ZERO_ERROR;
  198. * DateIntervalFormat* dtIntervalFmt = DateIntervalFormat::createInstance(
  199. * UDAT_YEAR_MONTH_DAY,
  200. * Locale("en", "GB", ""), status);
  201. * UnicodeUnicodeString dateIntervalString;
  202. * FieldPosition pos = 0;
  203. * // formatting
  204. * dtIntervalFmt->format(dtInterval, dateIntervalUnicodeString, pos, status);
  205. * delete dtIntervalFmt;
  206. * \endcode
  207. * </pre>
  208. */
  209. class U_I18N_API DateIntervalFormat : public Format {
  210. public:
  211. /**
  212. * Construct a DateIntervalFormat from skeleton and the default locale.
  213. *
  214. * This is a convenient override of
  215. * createInstance(const UnicodeString& skeleton, const Locale& locale,
  216. * UErrorCode&)
  217. * with the value of locale as default locale.
  218. *
  219. * @param skeleton the skeleton on which interval format based.
  220. * @param status output param set to success/failure code on exit
  221. * @return a date time interval formatter which the caller owns.
  222. * @stable ICU 4.0
  223. */
  224. static DateIntervalFormat* U_EXPORT2 createInstance(
  225. const UnicodeString& skeleton,
  226. UErrorCode& status);
  227. /**
  228. * Construct a DateIntervalFormat from skeleton and a given locale.
  229. * <P>
  230. * In this factory method,
  231. * the date interval pattern information is load from resource files.
  232. * Users are encouraged to created date interval formatter this way and
  233. * to use the pre-defined skeleton macros.
  234. *
  235. * <P>
  236. * There are pre-defined skeletons (defined in udate.h) having predefined
  237. * interval patterns in resource files.
  238. * Users are encouraged to use those macros.
  239. * For example:
  240. * DateIntervalFormat::createInstance(UDAT_MONTH_DAY, status)
  241. *
  242. * The given Locale provides the interval patterns.
  243. * For example, for en_GB, if skeleton is UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY,
  244. * which is "yMMMEEEd",
  245. * the interval patterns defined in resource file to above skeleton are:
  246. * "EEE, d MMM, yyyy - EEE, d MMM, yyyy" for year differs,
  247. * "EEE, d MMM - EEE, d MMM, yyyy" for month differs,
  248. * "EEE, d - EEE, d MMM, yyyy" for day differs,
  249. * @param skeleton the skeleton on which the interval format is based.
  250. * @param locale the given locale
  251. * @param status output param set to success/failure code on exit
  252. * @return a date time interval formatter which the caller owns.
  253. * @stable ICU 4.0
  254. * <p>
  255. * <h4>Sample code</h4>
  256. * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtPreDefined1
  257. * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtPreDefined
  258. * <p>
  259. */
  260. static DateIntervalFormat* U_EXPORT2 createInstance(
  261. const UnicodeString& skeleton,
  262. const Locale& locale,
  263. UErrorCode& status);
  264. /**
  265. * Construct a DateIntervalFormat from skeleton
  266. * DateIntervalInfo, and default locale.
  267. *
  268. * This is a convenient override of
  269. * createInstance(const UnicodeString& skeleton, const Locale& locale,
  270. * const DateIntervalInfo& dtitvinf, UErrorCode&)
  271. * with the locale value as default locale.
  272. *
  273. * @param skeleton the skeleton on which interval format based.
  274. * @param dtitvinf the DateIntervalInfo object.
  275. * @param status output param set to success/failure code on exit
  276. * @return a date time interval formatter which the caller owns.
  277. * @stable ICU 4.0
  278. */
  279. static DateIntervalFormat* U_EXPORT2 createInstance(
  280. const UnicodeString& skeleton,
  281. const DateIntervalInfo& dtitvinf,
  282. UErrorCode& status);
  283. /**
  284. * Construct a DateIntervalFormat from skeleton
  285. * a DateIntervalInfo, and the given locale.
  286. *
  287. * <P>
  288. * In this factory method, user provides its own date interval pattern
  289. * information, instead of using those pre-defined data in resource file.
  290. * This factory method is for powerful users who want to provide their own
  291. * interval patterns.
  292. * <P>
  293. * There are pre-defined skeletons (defined in udate.h) having predefined
  294. * interval patterns in resource files.
  295. * Users are encouraged to use those macros.
  296. * For example:
  297. * DateIntervalFormat::createInstance(UDAT_MONTH_DAY, status)
  298. *
  299. * The DateIntervalInfo provides the interval patterns.
  300. * and the DateIntervalInfo ownership remains to the caller.
  301. *
  302. * User are encouraged to set default interval pattern in DateIntervalInfo
  303. * as well, if they want to set other interval patterns ( instead of
  304. * reading the interval patterns from resource files).
  305. * When the corresponding interval pattern for a largest calendar different
  306. * field is not found ( if user not set it ), interval format fallback to
  307. * the default interval pattern.
  308. * If user does not provide default interval pattern, it fallback to
  309. * "{date0} - {date1}"
  310. *
  311. * @param skeleton the skeleton on which interval format based.
  312. * @param locale the given locale
  313. * @param dtitvinf the DateIntervalInfo object.
  314. * @param status output param set to success/failure code on exit
  315. * @return a date time interval formatter which the caller owns.
  316. * @stable ICU 4.0
  317. * <p>
  318. * <h4>Sample code</h4>
  319. * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtPreDefined1
  320. * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtCustomized
  321. * <p>
  322. */
  323. static DateIntervalFormat* U_EXPORT2 createInstance(
  324. const UnicodeString& skeleton,
  325. const Locale& locale,
  326. const DateIntervalInfo& dtitvinf,
  327. UErrorCode& status);
  328. /**
  329. * Destructor.
  330. * @stable ICU 4.0
  331. */
  332. virtual ~DateIntervalFormat();
  333. /**
  334. * Clone this Format object polymorphically. The caller owns the result and
  335. * should delete it when done.
  336. * @return A copy of the object.
  337. * @stable ICU 4.0
  338. */
  339. virtual Format* clone(void) const;
  340. /**
  341. * Return true if the given Format objects are semantically equal. Objects
  342. * of different subclasses are considered unequal.
  343. * @param other the object to be compared with.
  344. * @return true if the given Format objects are semantically equal.
  345. * @stable ICU 4.0
  346. */
  347. virtual UBool operator==(const Format& other) const;
  348. /**
  349. * Return true if the given Format objects are not semantically equal.
  350. * Objects of different subclasses are considered unequal.
  351. * @param other the object to be compared with.
  352. * @return true if the given Format objects are not semantically equal.
  353. * @stable ICU 4.0
  354. */
  355. UBool operator!=(const Format& other) const;
  356. using Format::format;
  357. /**
  358. * Format an object to produce a string. This method handles Formattable
  359. * objects with a DateInterval type.
  360. * If a the Formattable object type is not a DateInterval,
  361. * then it returns a failing UErrorCode.
  362. *
  363. * @param obj The object to format.
  364. * Must be a DateInterval.
  365. * @param appendTo Output parameter to receive result.
  366. * Result is appended to existing contents.
  367. * @param fieldPosition On input: an alignment field, if desired.
  368. * On output: the offsets of the alignment field.
  369. * There may be multiple instances of a given field type
  370. * in an interval format; in this case the fieldPosition
  371. * offsets refer to the first instance.
  372. * @param status Output param filled with success/failure status.
  373. * @return Reference to 'appendTo' parameter.
  374. * @stable ICU 4.0
  375. */
  376. virtual UnicodeString& format(const Formattable& obj,
  377. UnicodeString& appendTo,
  378. FieldPosition& fieldPosition,
  379. UErrorCode& status) const ;
  380. /**
  381. * Format a DateInterval to produce a string.
  382. *
  383. * @param dtInterval DateInterval to be formatted.
  384. * @param appendTo Output parameter to receive result.
  385. * Result is appended to existing contents.
  386. * @param fieldPosition On input: an alignment field, if desired.
  387. * On output: the offsets of the alignment field.
  388. * There may be multiple instances of a given field type
  389. * in an interval format; in this case the fieldPosition
  390. * offsets refer to the first instance.
  391. * @param status Output param filled with success/failure status.
  392. * @return Reference to 'appendTo' parameter.
  393. * @stable ICU 4.0
  394. */
  395. UnicodeString& format(const DateInterval* dtInterval,
  396. UnicodeString& appendTo,
  397. FieldPosition& fieldPosition,
  398. UErrorCode& status) const ;
  399. /**
  400. * Format 2 Calendars to produce a string.
  401. *
  402. * Note: "fromCalendar" and "toCalendar" are not const,
  403. * since calendar is not const in SimpleDateFormat::format(Calendar&),
  404. *
  405. * @param fromCalendar calendar set to the from date in date interval
  406. * to be formatted into date interval string
  407. * @param toCalendar calendar set to the to date in date interval
  408. * to be formatted into date interval string
  409. * @param appendTo Output parameter to receive result.
  410. * Result is appended to existing contents.
  411. * @param fieldPosition On input: an alignment field, if desired.
  412. * On output: the offsets of the alignment field.
  413. * There may be multiple instances of a given field type
  414. * in an interval format; in this case the fieldPosition
  415. * offsets refer to the first instance.
  416. * @param status Output param filled with success/failure status.
  417. * Caller needs to make sure it is SUCCESS
  418. * at the function entrance
  419. * @return Reference to 'appendTo' parameter.
  420. * @stable ICU 4.0
  421. */
  422. UnicodeString& format(Calendar& fromCalendar,
  423. Calendar& toCalendar,
  424. UnicodeString& appendTo,
  425. FieldPosition& fieldPosition,
  426. UErrorCode& status) const ;
  427. /**
  428. * Date interval parsing is not supported. Please do not use.
  429. * <P>
  430. * This method should handle parsing of
  431. * date time interval strings into Formattable objects with
  432. * DateInterval type, which is a pair of UDate.
  433. * <P>
  434. * Before calling, set parse_pos.index to the offset you want to start
  435. * parsing at in the source. After calling, parse_pos.index is the end of
  436. * the text you parsed. If error occurs, index is unchanged.
  437. * <P>
  438. * When parsing, leading whitespace is discarded (with a successful parse),
  439. * while trailing whitespace is left as is.
  440. * <P>
  441. * See Format::parseObject() for more.
  442. *
  443. * @param source The string to be parsed into an object.
  444. * @param result Formattable to be set to the parse result.
  445. * If parse fails, return contents are undefined.
  446. * @param parse_pos The position to start parsing at. Since no parsing
  447. * is supported, upon return this param is unchanged.
  448. * @return A newly created Formattable* object, or NULL
  449. * on failure. The caller owns this and should
  450. * delete it when done.
  451. * @internal ICU 4.0
  452. */
  453. virtual void parseObject(const UnicodeString& source,
  454. Formattable& result,
  455. ParsePosition& parse_pos) const;
  456. /**
  457. * Gets the date time interval patterns.
  458. * @return the date time interval patterns associated with
  459. * this date interval formatter.
  460. * @stable ICU 4.0
  461. */
  462. const DateIntervalInfo* getDateIntervalInfo(void) const;
  463. /**
  464. * Set the date time interval patterns.
  465. * @param newIntervalPatterns the given interval patterns to copy.
  466. * @param status output param set to success/failure code on exit
  467. * @stable ICU 4.0
  468. */
  469. void setDateIntervalInfo(const DateIntervalInfo& newIntervalPatterns,
  470. UErrorCode& status);
  471. /**
  472. * Gets the date formatter. The DateIntervalFormat instance continues to own
  473. * the returned DateFormatter object, and will use and possibly modify it
  474. * during format operations. In a multi-threaded environment, the returned
  475. * DateFormat can only be used if it is certain that no other threads are
  476. * concurrently using this DateIntervalFormatter, even for nominally const
  477. * functions.
  478. *
  479. * @return the date formatter associated with this date interval formatter.
  480. * @stable ICU 4.0
  481. */
  482. const DateFormat* getDateFormat(void) const;
  483. /**
  484. * Returns a reference to the TimeZone used by this DateIntervalFormat's calendar.
  485. * @return the time zone associated with the calendar of DateIntervalFormat.
  486. * @stable ICU 4.8
  487. */
  488. virtual const TimeZone& getTimeZone(void) const;
  489. /**
  490. * Sets the time zone for the calendar used by this DateIntervalFormat object. The
  491. * caller no longer owns the TimeZone object and should not delete it after this call.
  492. * @param zoneToAdopt the TimeZone to be adopted.
  493. * @stable ICU 4.8
  494. */
  495. virtual void adoptTimeZone(TimeZone* zoneToAdopt);
  496. /**
  497. * Sets the time zone for the calendar used by this DateIntervalFormat object.
  498. * @param zone the new time zone.
  499. * @stable ICU 4.8
  500. */
  501. virtual void setTimeZone(const TimeZone& zone);
  502. /**
  503. * Return the class ID for this class. This is useful only for comparing to
  504. * a return value from getDynamicClassID(). For example:
  505. * <pre>
  506. * . Base* polymorphic_pointer = createPolymorphicObject();
  507. * . if (polymorphic_pointer->getDynamicClassID() ==
  508. * . erived::getStaticClassID()) ...
  509. * </pre>
  510. * @return The class ID for all objects of this class.
  511. * @stable ICU 4.0
  512. */
  513. static UClassID U_EXPORT2 getStaticClassID(void);
  514. /**
  515. * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
  516. * method is to implement a simple version of RTTI, since not all C++
  517. * compilers support genuine RTTI. Polymorphic operator==() and clone()
  518. * methods call this method.
  519. *
  520. * @return The class ID for this object. All objects of a
  521. * given class have the same class ID. Objects of
  522. * other classes have different class IDs.
  523. * @stable ICU 4.0
  524. */
  525. virtual UClassID getDynamicClassID(void) const;
  526. protected:
  527. /**
  528. * Copy constructor.
  529. * @stable ICU 4.0
  530. */
  531. DateIntervalFormat(const DateIntervalFormat&);
  532. /**
  533. * Assignment operator.
  534. * @stable ICU 4.0
  535. */
  536. DateIntervalFormat& operator=(const DateIntervalFormat&);
  537. private:
  538. /*
  539. * This is for ICU internal use only. Please do not use.
  540. * Save the interval pattern information.
  541. * Interval pattern consists of 2 single date patterns and the separator.
  542. * For example, interval pattern "MMM d - MMM d, yyyy" consists
  543. * a single date pattern "MMM d", another single date pattern "MMM d, yyyy",
  544. * and a separator "-".
  545. * The pattern is divided into 2 parts. For above example,
  546. * the first part is "MMM d - ", and the second part is "MMM d, yyyy".
  547. * Also, the first date appears in an interval pattern could be
  548. * the earlier date or the later date.
  549. * And such information is saved in the interval pattern as well.
  550. */
  551. struct PatternInfo {
  552. UnicodeString firstPart;
  553. UnicodeString secondPart;
  554. /**
  555. * Whether the first date in interval pattern is later date or not.
  556. * Fallback format set the default ordering.
  557. * And for a particular interval pattern, the order can be
  558. * overriden by prefixing the interval pattern with "latestFirst:" or
  559. * "earliestFirst:"
  560. * For example, given 2 date, Jan 10, 2007 to Feb 10, 2007.
  561. * if the fallback format is "{0} - {1}",
  562. * and the pattern is "d MMM - d MMM yyyy", the interval format is
  563. * "10 Jan - 10 Feb, 2007".
  564. * If the pattern is "latestFirst:d MMM - d MMM yyyy",
  565. * the interval format is "10 Feb - 10 Jan, 2007"
  566. */
  567. UBool laterDateFirst;
  568. };
  569. /**
  570. * default constructor
  571. * @internal (private)
  572. */
  573. DateIntervalFormat();
  574. /**
  575. * Construct a DateIntervalFormat from DateFormat,
  576. * a DateIntervalInfo, and skeleton.
  577. * DateFormat provides the timezone, calendar,
  578. * full pattern, and date format symbols information.
  579. * It should be a SimpleDateFormat object which
  580. * has a pattern in it.
  581. * the DateIntervalInfo provides the interval patterns.
  582. *
  583. * Note: the DateIntervalFormat takes ownership of both
  584. * DateFormat and DateIntervalInfo objects.
  585. * Caller should not delete them.
  586. *
  587. * @param locale the locale of this date interval formatter.
  588. * @param dtItvInfo the DateIntervalInfo object to be adopted.
  589. * @param skeleton the skeleton of the date formatter
  590. * @param status output param set to success/failure code on exit
  591. */
  592. DateIntervalFormat(const Locale& locale, DateIntervalInfo* dtItvInfo,
  593. const UnicodeString* skeleton, UErrorCode& status);
  594. /**
  595. * Construct a DateIntervalFormat from DateFormat
  596. * and a DateIntervalInfo.
  597. *
  598. * It is a wrapper of the constructor.
  599. *
  600. * @param locale the locale of this date interval formatter.
  601. * @param dtitvinf the DateIntervalInfo object to be adopted.
  602. * @param skeleton the skeleton of this formatter.
  603. * @param status Output param set to success/failure code.
  604. * @return a date time interval formatter which the caller owns.
  605. */
  606. static DateIntervalFormat* U_EXPORT2 create(const Locale& locale,
  607. DateIntervalInfo* dtitvinf,
  608. const UnicodeString* skeleton,
  609. UErrorCode& status);
  610. /**
  611. * Below are for generating interval patterns local to the formatter
  612. */
  613. /**
  614. * Provide an updated FieldPosition posResult based on two formats,
  615. * the FieldPosition values for each of them, and the pattern used
  616. * to combine them. The idea is for posResult to indicate the first
  617. * instance (if any) of the specified field in the combined result,
  618. * with correct offsets.
  619. *
  620. * @param combiningPattern Pattern used to combine pat0 and pat1
  621. * @param pat0 Formatted date/time value to replace {0}
  622. * @param pos0 FieldPosition within pat0
  623. * @param pat1 Formatted date/time value to replace {1}
  624. * @param pos1 FieldPosition within pat1
  625. * @param posResult FieldPosition to be set to the correct
  626. * position of the first field instance when
  627. * pat0 and pat1 are combined using combiningPattern
  628. */
  629. static void
  630. adjustPosition(UnicodeString& combiningPattern, // has {0} and {1} in it
  631. UnicodeString& pat0, FieldPosition& pos0, // pattern and pos corresponding to {0}
  632. UnicodeString& pat1, FieldPosition& pos1, // pattern and pos corresponding to {1}
  633. FieldPosition& posResult);
  634. /**
  635. * Format 2 Calendars using fall-back interval pattern
  636. *
  637. * The full pattern used in this fall-back format is the
  638. * full pattern of the date formatter.
  639. *
  640. * gFormatterMutex must already be locked when calling this function.
  641. *
  642. * @param fromCalendar calendar set to the from date in date interval
  643. * to be formatted into date interval string
  644. * @param toCalendar calendar set to the to date in date interval
  645. * to be formatted into date interval string
  646. * @param fromToOnSameDay TRUE iff from and to dates are on the same day
  647. * (any difference is in ampm/hours or below)
  648. * @param appendTo Output parameter to receive result.
  649. * Result is appended to existing contents.
  650. * @param pos On input: an alignment field, if desired.
  651. * On output: the offsets of the alignment field.
  652. * @param status output param set to success/failure code on exit
  653. * @return Reference to 'appendTo' parameter.
  654. * @internal (private)
  655. */
  656. UnicodeString& fallbackFormat(Calendar& fromCalendar,
  657. Calendar& toCalendar,
  658. UBool fromToOnSameDay,
  659. UnicodeString& appendTo,
  660. FieldPosition& pos,
  661. UErrorCode& status) const;
  662. /**
  663. * Initialize interval patterns locale to this formatter
  664. *
  665. * This code is a bit complicated since
  666. * 1. the interval patterns saved in resource bundle files are interval
  667. * patterns based on date or time only.
  668. * It does not have interval patterns based on both date and time.
  669. * Interval patterns on both date and time are algorithm generated.
  670. *
  671. * For example, it has interval patterns on skeleton "dMy" and "hm",
  672. * but it does not have interval patterns on skeleton "dMyhm".
  673. *
  674. * The rule to generate interval patterns for both date and time skeleton are
  675. * 1) when the year, month, or day differs, concatenate the two original
  676. * expressions with a separator between,
  677. * For example, interval pattern from "Jan 10, 2007 10:10 am"
  678. * to "Jan 11, 2007 10:10am" is
  679. * "Jan 10, 2007 10:10 am - Jan 11, 2007 10:10am"
  680. *
  681. * 2) otherwise, present the date followed by the range expression
  682. * for the time.
  683. * For example, interval pattern from "Jan 10, 2007 10:10 am"
  684. * to "Jan 10, 2007 11:10am" is
  685. * "Jan 10, 2007 10:10 am - 11:10am"
  686. *
  687. * 2. even a pattern does not request a certain calendar field,
  688. * the interval pattern needs to include such field if such fields are
  689. * different between 2 dates.
  690. * For example, a pattern/skeleton is "hm", but the interval pattern
  691. * includes year, month, and date when year, month, and date differs.
  692. *
  693. *
  694. * @param status output param set to success/failure code on exit
  695. */
  696. void initializePattern(UErrorCode& status);
  697. /**
  698. * Set fall back interval pattern given a calendar field,
  699. * a skeleton, and a date time pattern generator.
  700. * @param field the largest different calendar field
  701. * @param skeleton a skeleton
  702. * @param status output param set to success/failure code on exit
  703. */
  704. void setFallbackPattern(UCalendarDateFields field,
  705. const UnicodeString& skeleton,
  706. UErrorCode& status);
  707. /**
  708. * get separated date and time skeleton from a combined skeleton.
  709. *
  710. * The difference between date skeleton and normalizedDateSkeleton are:
  711. * 1. both 'y' and 'd' are appeared only once in normalizeDateSkeleton
  712. * 2. 'E' and 'EE' are normalized into 'EEE'
  713. * 3. 'MM' is normalized into 'M'
  714. *
  715. ** the difference between time skeleton and normalizedTimeSkeleton are:
  716. * 1. both 'H' and 'h' are normalized as 'h' in normalized time skeleton,
  717. * 2. 'a' is omitted in normalized time skeleton.
  718. * 3. there is only one appearance for 'h', 'm','v', 'z' in normalized time
  719. * skeleton
  720. *
  721. *
  722. * @param skeleton given combined skeleton.
  723. * @param date Output parameter for date only skeleton.
  724. * @param normalizedDate Output parameter for normalized date only
  725. *
  726. * @param time Output parameter for time only skeleton.
  727. * @param normalizedTime Output parameter for normalized time only
  728. * skeleton.
  729. *
  730. */
  731. static void U_EXPORT2 getDateTimeSkeleton(const UnicodeString& skeleton,
  732. UnicodeString& date,
  733. UnicodeString& normalizedDate,
  734. UnicodeString& time,
  735. UnicodeString& normalizedTime);
  736. /**
  737. * Generate date or time interval pattern from resource,
  738. * and set them into the interval pattern locale to this formatter.
  739. *
  740. * It needs to handle the following:
  741. * 1. need to adjust field width.
  742. * For example, the interval patterns saved in DateIntervalInfo
  743. * includes "dMMMy", but not "dMMMMy".
  744. * Need to get interval patterns for dMMMMy from dMMMy.
  745. * Another example, the interval patterns saved in DateIntervalInfo
  746. * includes "hmv", but not "hmz".
  747. * Need to get interval patterns for "hmz' from 'hmv'
  748. *
  749. * 2. there might be no pattern for 'y' differ for skeleton "Md",
  750. * in order to get interval patterns for 'y' differ,
  751. * need to look for it from skeleton 'yMd'
  752. *
  753. * @param dateSkeleton normalized date skeleton
  754. * @param timeSkeleton normalized time skeleton
  755. * @return whether the resource is found for the skeleton.
  756. * TRUE if interval pattern found for the skeleton,
  757. * FALSE otherwise.
  758. */
  759. UBool setSeparateDateTimePtn(const UnicodeString& dateSkeleton,
  760. const UnicodeString& timeSkeleton);
  761. /**
  762. * Generate interval pattern from existing resource
  763. *
  764. * It not only save the interval patterns,
  765. * but also return the extended skeleton and its best match skeleton.
  766. *
  767. * @param field largest different calendar field
  768. * @param skeleton skeleton
  769. * @param bestSkeleton the best match skeleton which has interval pattern
  770. * defined in resource
  771. * @param differenceInfo the difference between skeleton and best skeleton
  772. * 0 means the best matched skeleton is the same as input skeleton
  773. * 1 means the fields are the same, but field width are different
  774. * 2 means the only difference between fields are v/z,
  775. * -1 means there are other fields difference
  776. *
  777. * @param extendedSkeleton extended skeleton
  778. * @param extendedBestSkeleton extended best match skeleton
  779. * @return whether the interval pattern is found
  780. * through extending skeleton or not.
  781. * TRUE if interval pattern is found by
  782. * extending skeleton, FALSE otherwise.
  783. */
  784. UBool setIntervalPattern(UCalendarDateFields field,
  785. const UnicodeString* skeleton,
  786. const UnicodeString* bestSkeleton,
  787. int8_t differenceInfo,
  788. UnicodeString* extendedSkeleton = NULL,
  789. UnicodeString* extendedBestSkeleton = NULL);
  790. /**
  791. * Adjust field width in best match interval pattern to match
  792. * the field width in input skeleton.
  793. *
  794. * TODO (xji) make a general solution
  795. * The adjusting rule can be:
  796. * 1. always adjust
  797. * 2. never adjust
  798. * 3. default adjust, which means adjust according to the following rules
  799. * 3.1 always adjust string, such as MMM and MMMM
  800. * 3.2 never adjust between string and numeric, such as MM and MMM
  801. * 3.3 always adjust year
  802. * 3.4 do not adjust 'd', 'h', or 'm' if h presents
  803. * 3.5 do not adjust 'M' if it is numeric(?)
  804. *
  805. * Since date interval format is well-formed format,
  806. * date and time skeletons are normalized previously,
  807. * till this stage, the adjust here is only "adjust strings, such as MMM
  808. * and MMMM, EEE and EEEE.
  809. *
  810. * @param inputSkeleton the input skeleton
  811. * @param bestMatchSkeleton the best match skeleton
  812. * @param bestMatchIntervalPattern the best match interval pattern
  813. * @param differenceInfo the difference between 2 skeletons
  814. * 1 means only field width differs
  815. * 2 means v/z exchange
  816. * @param adjustedIntervalPattern adjusted interval pattern
  817. */
  818. static void U_EXPORT2 adjustFieldWidth(
  819. const UnicodeString& inputSkeleton,
  820. const UnicodeString& bestMatchSkeleton,
  821. const UnicodeString& bestMatchIntervalPattern,
  822. int8_t differenceInfo,
  823. UnicodeString& adjustedIntervalPattern);
  824. /**
  825. * Concat a single date pattern with a time interval pattern,
  826. * set it into the intervalPatterns, while field is time field.
  827. * This is used to handle time interval patterns on skeleton with
  828. * both time and date. Present the date followed by
  829. * the range expression for the time.
  830. * @param format date and time format
  831. * @param datePattern date pattern
  832. * @param field time calendar field: AM_PM, HOUR, MINUTE
  833. * @param status output param set to success/failure code on exit
  834. */
  835. void concatSingleDate2TimeInterval(UnicodeString& format,
  836. const UnicodeString& datePattern,
  837. UCalendarDateFields field,
  838. UErrorCode& status);
  839. /**
  840. * check whether a calendar field present in a skeleton.
  841. * @param field calendar field need to check
  842. * @param skeleton given skeleton on which to check the calendar field
  843. * @return true if field present in a skeleton.
  844. */
  845. static UBool U_EXPORT2 fieldExistsInSkeleton(UCalendarDateFields field,
  846. const UnicodeString& skeleton);
  847. /**
  848. * Split interval patterns into 2 part.
  849. * @param intervalPattern interval pattern
  850. * @return the index in interval pattern which split the pattern into 2 part
  851. */
  852. static int32_t U_EXPORT2 splitPatternInto2Part(const UnicodeString& intervalPattern);
  853. /**
  854. * Break interval patterns as 2 part and save them into pattern info.
  855. * @param field calendar field
  856. * @param intervalPattern interval pattern
  857. */
  858. void setIntervalPattern(UCalendarDateFields field,
  859. const UnicodeString& intervalPattern);
  860. /**
  861. * Break interval patterns as 2 part and save them into pattern info.
  862. * @param field calendar field
  863. * @param intervalPattern interval pattern
  864. * @param laterDateFirst whether later date appear first in interval pattern
  865. */
  866. void setIntervalPattern(UCalendarDateFields field,
  867. const UnicodeString& intervalPattern,
  868. UBool laterDateFirst);
  869. /**
  870. * Set pattern information.
  871. *
  872. * @param field calendar field
  873. * @param firstPart the first part in interval pattern
  874. * @param secondPart the second part in interval pattern
  875. * @param laterDateFirst whether the first date in intervalPattern
  876. * is earlier date or later date
  877. */
  878. void setPatternInfo(UCalendarDateFields field,
  879. const UnicodeString* firstPart,
  880. const UnicodeString* secondPart,
  881. UBool laterDateFirst);
  882. /**
  883. * Format 2 Calendars to produce a string.
  884. * Implementation of the similar public format function.
  885. * Must be called with gFormatterMutex already locked.
  886. *
  887. * Note: "fromCalendar" and "toCalendar" are not const,
  888. * since calendar is not const in SimpleDateFormat::format(Calendar&),
  889. *
  890. * @param fromCalendar calendar set to the from date in date interval
  891. * to be formatted into date interval string
  892. * @param toCalendar calendar set to the to date in date interval
  893. * to be formatted into date interval string
  894. * @param appendTo Output parameter to receive result.
  895. * Result is appended to existing contents.
  896. * @param fieldPosition On input: an alignment field, if desired.
  897. * On output: the offsets of the alignment field.
  898. * There may be multiple instances of a given field type
  899. * in an interval format; in this case the fieldPosition
  900. * offsets refer to the first instance.
  901. * @param status Output param filled with success/failure status.
  902. * Caller needs to make sure it is SUCCESS
  903. * at the function entrance
  904. * @return Reference to 'appendTo' parameter.
  905. * @internal (private)
  906. */
  907. UnicodeString& formatImpl(Calendar& fromCalendar,
  908. Calendar& toCalendar,
  909. UnicodeString& appendTo,
  910. FieldPosition& fieldPosition,
  911. UErrorCode& status) const ;
  912. // from calendar field to pattern letter
  913. static const UChar fgCalendarFieldToPatternLetter[];
  914. /**
  915. * The interval patterns for this locale.
  916. */
  917. DateIntervalInfo* fInfo;
  918. /**
  919. * The DateFormat object used to format single pattern
  920. */
  921. SimpleDateFormat* fDateFormat;
  922. /**
  923. * The 2 calendars with the from and to date.
  924. * could re-use the calendar in fDateFormat,
  925. * but keeping 2 calendars make it clear and clean.
  926. */
  927. Calendar* fFromCalendar;
  928. Calendar* fToCalendar;
  929. Locale fLocale;
  930. /**
  931. * Following are interval information relevant (locale) to this formatter.
  932. */
  933. UnicodeString fSkeleton;
  934. PatternInfo fIntervalPatterns[DateIntervalInfo::kIPI_MAX_INDEX];
  935. /**
  936. * Patterns for fallback formatting.
  937. */
  938. UnicodeString* fDatePattern;
  939. UnicodeString* fTimePattern;
  940. UnicodeString* fDateTimeFormat;
  941. };
  942. inline UBool
  943. DateIntervalFormat::operator!=(const Format& other) const {
  944. return !operator==(other);
  945. }
  946. U_NAMESPACE_END
  947. #endif /* #if !UCONFIG_NO_FORMATTING */
  948. #endif // _DTITVFMT_H__
  949. //eof