dtitvinf.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. *******************************************************************************
  3. * Copyright (C) 2008-2016, International Business Machines Corporation and
  4. * others. All Rights Reserved.
  5. *******************************************************************************
  6. *
  7. * File DTITVINF.H
  8. *
  9. *******************************************************************************
  10. */
  11. #ifndef __DTITVINF_H__
  12. #define __DTITVINF_H__
  13. #include "unicode/utypes.h"
  14. /**
  15. * \file
  16. * \brief C++ API: Date/Time interval patterns for formatting date/time interval
  17. */
  18. #if !UCONFIG_NO_FORMATTING
  19. #include "unicode/udat.h"
  20. #include "unicode/locid.h"
  21. #include "unicode/ucal.h"
  22. #include "unicode/dtptngen.h"
  23. U_NAMESPACE_BEGIN
  24. /**
  25. * DateIntervalInfo is a public class for encapsulating localizable
  26. * date time interval patterns. It is used by DateIntervalFormat.
  27. *
  28. * <P>
  29. * For most users, ordinary use of DateIntervalFormat does not need to create
  30. * DateIntervalInfo object directly.
  31. * DateIntervalFormat will take care of it when creating a date interval
  32. * formatter when user pass in skeleton and locale.
  33. *
  34. * <P>
  35. * For power users, who want to create their own date interval patterns,
  36. * or want to re-set date interval patterns, they could do so by
  37. * directly creating DateIntervalInfo and manupulating it.
  38. *
  39. * <P>
  40. * Logically, the interval patterns are mappings
  41. * from (skeleton, the_largest_different_calendar_field)
  42. * to (date_interval_pattern).
  43. *
  44. * <P>
  45. * A skeleton
  46. * <ol>
  47. * <li>
  48. * only keeps the field pattern letter and ignores all other parts
  49. * in a pattern, such as space, punctuations, and string literals.
  50. * <li>
  51. * hides the order of fields.
  52. * <li>
  53. * might hide a field's pattern letter length.
  54. *
  55. * For those non-digit calendar fields, the pattern letter length is
  56. * important, such as MMM, MMMM, and MMMMM; EEE and EEEE,
  57. * and the field's pattern letter length is honored.
  58. *
  59. * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy,
  60. * the field pattern length is ignored and the best match, which is defined
  61. * in date time patterns, will be returned without honor the field pattern
  62. * letter length in skeleton.
  63. * </ol>
  64. *
  65. * <P>
  66. * The calendar fields we support for interval formatting are:
  67. * year, month, date, day-of-week, am-pm, hour, hour-of-day, and minute.
  68. * Those calendar fields can be defined in the following order:
  69. * year > month > date > am-pm > hour > minute
  70. *
  71. * The largest different calendar fields between 2 calendars is the
  72. * first different calendar field in above order.
  73. *
  74. * For example: the largest different calendar fields between &quot;Jan 10, 2007&quot;
  75. * and &quot;Feb 20, 2008&quot; is year.
  76. *
  77. * <P>
  78. * There is a set of pre-defined static skeleton strings.
  79. * There are pre-defined interval patterns for those pre-defined skeletons
  80. * in locales' resource files.
  81. * For example, for a skeleton UDAT_YEAR_ABBR_MONTH_DAY, which is &quot;yMMMd&quot;,
  82. * in en_US, if the largest different calendar field between date1 and date2
  83. * is &quot;year&quot;, the date interval pattern is &quot;MMM d, yyyy - MMM d, yyyy&quot;,
  84. * such as &quot;Jan 10, 2007 - Jan 10, 2008&quot;.
  85. * If the largest different calendar field between date1 and date2 is &quot;month&quot;,
  86. * the date interval pattern is &quot;MMM d - MMM d, yyyy&quot;,
  87. * such as &quot;Jan 10 - Feb 10, 2007&quot;.
  88. * If the largest different calendar field between date1 and date2 is &quot;day&quot;,
  89. * the date interval pattern is &quot;MMM d-d, yyyy&quot;, such as &quot;Jan 10-20, 2007&quot;.
  90. *
  91. * For date skeleton, the interval patterns when year, or month, or date is
  92. * different are defined in resource files.
  93. * For time skeleton, the interval patterns when am/pm, or hour, or minute is
  94. * different are defined in resource files.
  95. *
  96. *
  97. * <P>
  98. * There are 2 dates in interval pattern. For most locales, the first date
  99. * in an interval pattern is the earlier date. There might be a locale in which
  100. * the first date in an interval pattern is the later date.
  101. * We use fallback format for the default order for the locale.
  102. * For example, if the fallback format is &quot;{0} - {1}&quot;, it means
  103. * the first date in the interval pattern for this locale is earlier date.
  104. * If the fallback format is &quot;{1} - {0}&quot;, it means the first date is the
  105. * later date.
  106. * For a particular interval pattern, the default order can be overriden
  107. * by prefixing &quot;latestFirst:&quot; or &quot;earliestFirst:&quot; to the interval pattern.
  108. * For example, if the fallback format is &quot;{0}-{1}&quot;,
  109. * but for skeleton &quot;yMMMd&quot;, the interval pattern when day is different is
  110. * &quot;latestFirst:d-d MMM yy&quot;, it means by default, the first date in interval
  111. * pattern is the earlier date. But for skeleton &quot;yMMMd&quot;, when day is different,
  112. * the first date in &quot;d-d MMM yy&quot; is the later date.
  113. *
  114. * <P>
  115. * The recommended way to create a DateIntervalFormat object is to pass in
  116. * the locale.
  117. * By using a Locale parameter, the DateIntervalFormat object is
  118. * initialized with the pre-defined interval patterns for a given or
  119. * default locale.
  120. * <P>
  121. * Users can also create DateIntervalFormat object
  122. * by supplying their own interval patterns.
  123. * It provides flexibility for power users.
  124. *
  125. * <P>
  126. * After a DateIntervalInfo object is created, clients may modify
  127. * the interval patterns using setIntervalPattern function as so desired.
  128. * Currently, users can only set interval patterns when the following
  129. * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH,
  130. * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, and MINUTE.
  131. * Interval patterns when other calendar fields are different is not supported.
  132. * <P>
  133. * DateIntervalInfo objects are cloneable.
  134. * When clients obtain a DateIntervalInfo object,
  135. * they can feel free to modify it as necessary.
  136. * <P>
  137. * DateIntervalInfo are not expected to be subclassed.
  138. * Data for a calendar is loaded out of resource bundles.
  139. * Through ICU 4.4, date interval patterns are only supported in the Gregorian
  140. * calendar; non-Gregorian calendars are supported from ICU 4.4.1.
  141. * @stable ICU 4.0
  142. **/
  143. class U_I18N_API DateIntervalInfo U_FINAL : public UObject {
  144. public:
  145. #ifndef U_HIDE_INTERNAL_API
  146. /**
  147. * Default constructor.
  148. * It does not initialize any interval patterns except
  149. * that it initialize default fall-back pattern as "{0} - {1}",
  150. * which can be reset by setFallbackIntervalPattern().
  151. * It should be followed by setFallbackIntervalPattern() and
  152. * setIntervalPattern(),
  153. * and is recommended to be used only for power users who
  154. * wants to create their own interval patterns and use them to create
  155. * date interval formatter.
  156. * @param status output param set to success/failure code on exit
  157. * @internal ICU 4.0
  158. */
  159. DateIntervalInfo(UErrorCode& status);
  160. #endif /* U_HIDE_INTERNAL_API */
  161. /**
  162. * Construct DateIntervalInfo for the given locale,
  163. * @param locale the interval patterns are loaded from the appropriate calendar
  164. * data (specified calendar or default calendar) in this locale.
  165. * @param status output param set to success/failure code on exit
  166. * @stable ICU 4.0
  167. */
  168. DateIntervalInfo(const Locale& locale, UErrorCode& status);
  169. /**
  170. * Copy constructor.
  171. * @stable ICU 4.0
  172. */
  173. DateIntervalInfo(const DateIntervalInfo&);
  174. /**
  175. * Assignment operator
  176. * @stable ICU 4.0
  177. */
  178. DateIntervalInfo& operator=(const DateIntervalInfo&);
  179. /**
  180. * Clone this object polymorphically.
  181. * The caller owns the result and should delete it when done.
  182. * @return a copy of the object
  183. * @stable ICU 4.0
  184. */
  185. virtual DateIntervalInfo* clone(void) const;
  186. /**
  187. * Destructor.
  188. * It is virtual to be safe, but it is not designed to be subclassed.
  189. * @stable ICU 4.0
  190. */
  191. virtual ~DateIntervalInfo();
  192. /**
  193. * Return true if another object is semantically equal to this one.
  194. *
  195. * @param other the DateIntervalInfo object to be compared with.
  196. * @return true if other is semantically equal to this.
  197. * @stable ICU 4.0
  198. */
  199. virtual UBool operator==(const DateIntervalInfo& other) const;
  200. /**
  201. * Return true if another object is semantically unequal to this one.
  202. *
  203. * @param other the DateIntervalInfo object to be compared with.
  204. * @return true if other is semantically unequal to this.
  205. * @stable ICU 4.0
  206. */
  207. UBool operator!=(const DateIntervalInfo& other) const;
  208. /**
  209. * Provides a way for client to build interval patterns.
  210. * User could construct DateIntervalInfo by providing a list of skeletons
  211. * and their patterns.
  212. * <P>
  213. * For example:
  214. * <pre>
  215. * UErrorCode status = U_ZERO_ERROR;
  216. * DateIntervalInfo dIntervalInfo = new DateIntervalInfo();
  217. * dIntervalInfo->setFallbackIntervalPattern("{0} ~ {1}");
  218. * dIntervalInfo->setIntervalPattern("yMd", UCAL_YEAR, "'from' yyyy-M-d 'to' yyyy-M-d", status);
  219. * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_MONTH, "'from' yyyy MMM d 'to' MMM d", status);
  220. * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_DAY, "yyyy MMM d-d", status, status);
  221. * </pre>
  222. *
  223. * Restriction:
  224. * Currently, users can only set interval patterns when the following
  225. * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH,
  226. * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, and MINUTE.
  227. * Interval patterns when other calendar fields are different are
  228. * not supported.
  229. *
  230. * @param skeleton the skeleton on which interval pattern based
  231. * @param lrgDiffCalUnit the largest different calendar unit.
  232. * @param intervalPattern the interval pattern on the largest different
  233. * calendar unit.
  234. * For example, if lrgDiffCalUnit is
  235. * "year", the interval pattern for en_US when year
  236. * is different could be "'from' yyyy 'to' yyyy".
  237. * @param status output param set to success/failure code on exit
  238. * @stable ICU 4.0
  239. */
  240. void setIntervalPattern(const UnicodeString& skeleton,
  241. UCalendarDateFields lrgDiffCalUnit,
  242. const UnicodeString& intervalPattern,
  243. UErrorCode& status);
  244. /**
  245. * Get the interval pattern given skeleton and
  246. * the largest different calendar field.
  247. * @param skeleton the skeleton
  248. * @param field the largest different calendar field
  249. * @param result output param to receive the pattern
  250. * @param status output param set to success/failure code on exit
  251. * @return a reference to 'result'
  252. * @stable ICU 4.0
  253. */
  254. UnicodeString& getIntervalPattern(const UnicodeString& skeleton,
  255. UCalendarDateFields field,
  256. UnicodeString& result,
  257. UErrorCode& status) const;
  258. /**
  259. * Get the fallback interval pattern.
  260. * @param result output param to receive the pattern
  261. * @return a reference to 'result'
  262. * @stable ICU 4.0
  263. */
  264. UnicodeString& getFallbackIntervalPattern(UnicodeString& result) const;
  265. /**
  266. * Re-set the fallback interval pattern.
  267. *
  268. * In construction, default fallback pattern is set as "{0} - {1}".
  269. * And constructor taking locale as parameter will set the
  270. * fallback pattern as what defined in the locale resource file.
  271. *
  272. * This method provides a way for user to replace the fallback pattern.
  273. *
  274. * @param fallbackPattern fall-back interval pattern.
  275. * @param status output param set to success/failure code on exit
  276. * @stable ICU 4.0
  277. */
  278. void setFallbackIntervalPattern(const UnicodeString& fallbackPattern,
  279. UErrorCode& status);
  280. /** Get default order -- whether the first date in pattern is later date
  281. or not.
  282. * return default date ordering in interval pattern. TRUE if the first date
  283. * in pattern is later date, FALSE otherwise.
  284. * @stable ICU 4.0
  285. */
  286. UBool getDefaultOrder() const;
  287. /**
  288. * ICU "poor man's RTTI", returns a UClassID for the actual class.
  289. *
  290. * @stable ICU 4.0
  291. */
  292. virtual UClassID getDynamicClassID() const;
  293. /**
  294. * ICU "poor man's RTTI", returns a UClassID for this class.
  295. *
  296. * @stable ICU 4.0
  297. */
  298. static UClassID U_EXPORT2 getStaticClassID();
  299. private:
  300. /**
  301. * DateIntervalFormat will need access to
  302. * getBestSkeleton(), parseSkeleton(), enum IntervalPatternIndex,
  303. * and calendarFieldToPatternIndex().
  304. *
  305. * Instead of making above public,
  306. * make DateIntervalFormat a friend of DateIntervalInfo.
  307. */
  308. friend class DateIntervalFormat;
  309. friend struct DateIntervalSink;
  310. /**
  311. * Following is for saving the interval patterns.
  312. * We only support interval patterns on
  313. * ERA, YEAR, MONTH, DAY, AM_PM, HOUR, and MINUTE
  314. */
  315. enum IntervalPatternIndex
  316. {
  317. kIPI_ERA,
  318. kIPI_YEAR,
  319. kIPI_MONTH,
  320. kIPI_DATE,
  321. kIPI_AM_PM,
  322. kIPI_HOUR,
  323. kIPI_MINUTE,
  324. kIPI_SECOND,
  325. kIPI_MAX_INDEX
  326. };
  327. public:
  328. #ifndef U_HIDE_INTERNAL_API
  329. /**
  330. * Max index for stored interval patterns
  331. * @internal ICU 4.4
  332. */
  333. enum {
  334. kMaxIntervalPatternIndex = kIPI_MAX_INDEX
  335. };
  336. #endif /* U_HIDE_INTERNAL_API */
  337. private:
  338. /**
  339. * Initialize the DateIntervalInfo from locale
  340. * @param locale the given locale.
  341. * @param status output param set to success/failure code on exit
  342. */
  343. void initializeData(const Locale& locale, UErrorCode& status);
  344. /* Set Interval pattern.
  345. *
  346. * It sets interval pattern into the hash map.
  347. *
  348. * @param skeleton skeleton on which the interval pattern based
  349. * @param lrgDiffCalUnit the largest different calendar unit.
  350. * @param intervalPattern the interval pattern on the largest different
  351. * calendar unit.
  352. * @param status output param set to success/failure code on exit
  353. */
  354. void setIntervalPatternInternally(const UnicodeString& skeleton,
  355. UCalendarDateFields lrgDiffCalUnit,
  356. const UnicodeString& intervalPattern,
  357. UErrorCode& status);
  358. /**given an input skeleton, get the best match skeleton
  359. * which has pre-defined interval pattern in resource file.
  360. * Also return the difference between the input skeleton
  361. * and the best match skeleton.
  362. *
  363. * TODO (xji): set field weight or
  364. * isolate the funtionality in DateTimePatternGenerator
  365. * @param skeleton input skeleton
  366. * @param bestMatchDistanceInfo the difference between input skeleton
  367. * and best match skeleton.
  368. * 0, if there is exact match for input skeleton
  369. * 1, if there is only field width difference between
  370. * the best match and the input skeleton
  371. * 2, the only field difference is 'v' and 'z'
  372. * -1, if there is calendar field difference between
  373. * the best match and the input skeleton
  374. * @return best match skeleton
  375. */
  376. const UnicodeString* getBestSkeleton(const UnicodeString& skeleton,
  377. int8_t& bestMatchDistanceInfo) const;
  378. /**
  379. * Parse skeleton, save each field's width.
  380. * It is used for looking for best match skeleton,
  381. * and adjust pattern field width.
  382. * @param skeleton skeleton to be parsed
  383. * @param skeletonFieldWidth parsed skeleton field width
  384. */
  385. static void U_EXPORT2 parseSkeleton(const UnicodeString& skeleton,
  386. int32_t* skeletonFieldWidth);
  387. /**
  388. * Check whether one field width is numeric while the other is string.
  389. *
  390. * TODO (xji): make it general
  391. *
  392. * @param fieldWidth one field width
  393. * @param anotherFieldWidth another field width
  394. * @param patternLetter pattern letter char
  395. * @return true if one field width is numeric and the other is string,
  396. * false otherwise.
  397. */
  398. static UBool U_EXPORT2 stringNumeric(int32_t fieldWidth,
  399. int32_t anotherFieldWidth,
  400. char patternLetter);
  401. /**
  402. * Convert calendar field to the interval pattern index in
  403. * hash table.
  404. *
  405. * Since we only support the following calendar fields:
  406. * ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, DAY_OF_WEEK,
  407. * AM_PM, HOUR, HOUR_OF_DAY, and MINUTE,
  408. * We reserve only 4 interval patterns for a skeleton.
  409. *
  410. * @param field calendar field
  411. * @param status output param set to success/failure code on exit
  412. * @return interval pattern index in hash table
  413. */
  414. static IntervalPatternIndex U_EXPORT2 calendarFieldToIntervalIndex(
  415. UCalendarDateFields field,
  416. UErrorCode& status);
  417. /**
  418. * delete hash table (of type fIntervalPatterns).
  419. *
  420. * @param hTable hash table to be deleted
  421. */
  422. void deleteHash(Hashtable* hTable);
  423. /**
  424. * initialize hash table (of type fIntervalPatterns).
  425. *
  426. * @param status output param set to success/failure code on exit
  427. * @return hash table initialized
  428. */
  429. Hashtable* initHash(UErrorCode& status);
  430. /**
  431. * copy hash table (of type fIntervalPatterns).
  432. *
  433. * @param source the source to copy from
  434. * @param target the target to copy to
  435. * @param status output param set to success/failure code on exit
  436. */
  437. void copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status);
  438. // data members
  439. // fallback interval pattern
  440. UnicodeString fFallbackIntervalPattern;
  441. // default order
  442. UBool fFirstDateInPtnIsLaterDate;
  443. // HashMap<UnicodeString, UnicodeString[kIPI_MAX_INDEX]>
  444. // HashMap( skeleton, pattern[largest_different_field] )
  445. Hashtable* fIntervalPatterns;
  446. };// end class DateIntervalInfo
  447. inline UBool
  448. DateIntervalInfo::operator!=(const DateIntervalInfo& other) const {
  449. return !operator==(other);
  450. }
  451. U_NAMESPACE_END
  452. #endif
  453. #endif