dtitvinf.h 19 KB

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