dtitvinf.h 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. // © 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. #if U_SHOW_CPLUSPLUS_API
  17. /**
  18. * \file
  19. * \brief C++ API: Date/Time interval patterns for formatting date/time interval
  20. */
  21. #if !UCONFIG_NO_FORMATTING
  22. #include "unicode/udat.h"
  23. #include "unicode/locid.h"
  24. #include "unicode/ucal.h"
  25. #include "unicode/dtptngen.h"
  26. U_NAMESPACE_BEGIN
  27. /**
  28. * DateIntervalInfo is a public class for encapsulating localizable
  29. * date time interval patterns. It is used by DateIntervalFormat.
  30. *
  31. * <P>
  32. * For most users, ordinary use of DateIntervalFormat does not need to create
  33. * DateIntervalInfo object directly.
  34. * DateIntervalFormat will take care of it when creating a date interval
  35. * formatter when user pass in skeleton and locale.
  36. *
  37. * <P>
  38. * For power users, who want to create their own date interval patterns,
  39. * or want to re-set date interval patterns, they could do so by
  40. * directly creating DateIntervalInfo and manipulating it.
  41. *
  42. * <P>
  43. * Logically, the interval patterns are mappings
  44. * from (skeleton, the_largest_different_calendar_field)
  45. * to (date_interval_pattern).
  46. *
  47. * <P>
  48. * A skeleton
  49. * <ol>
  50. * <li>
  51. * only keeps the field pattern letter and ignores all other parts
  52. * in a pattern, such as space, punctuations, and string literals.
  53. * <li>
  54. * hides the order of fields.
  55. * <li>
  56. * might hide a field's pattern letter length.
  57. *
  58. * For those non-digit calendar fields, the pattern letter length is
  59. * important, such as MMM, MMMM, and MMMMM; EEE and EEEE,
  60. * and the field's pattern letter length is honored.
  61. *
  62. * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy,
  63. * the field pattern length is ignored and the best match, which is defined
  64. * in date time patterns, will be returned without honor the field pattern
  65. * letter length in skeleton.
  66. * </ol>
  67. *
  68. * <P>
  69. * The calendar fields we support for interval formatting are:
  70. * year, month, date, day-of-week, am-pm, hour, hour-of-day, and minute.
  71. * Those calendar fields can be defined in the following order:
  72. * year > month > date > am-pm > hour > minute
  73. *
  74. * The largest different calendar fields between 2 calendars is the
  75. * first different calendar field in above order.
  76. *
  77. * For example: the largest different calendar fields between &quot;Jan 10, 2007&quot;
  78. * and &quot;Feb 20, 2008&quot; is year.
  79. *
  80. * <P>
  81. * There is a set of pre-defined static skeleton strings.
  82. * There are pre-defined interval patterns for those pre-defined skeletons
  83. * in locales' resource files.
  84. * For example, for a skeleton UDAT_YEAR_ABBR_MONTH_DAY, which is &quot;yMMMd&quot;,
  85. * in en_US, if the largest different calendar field between date1 and date2
  86. * is &quot;year&quot;, the date interval pattern is &quot;MMM d, yyyy - MMM d, yyyy&quot;,
  87. * such as &quot;Jan 10, 2007 - Jan 10, 2008&quot;.
  88. * If the largest different calendar field between date1 and date2 is &quot;month&quot;,
  89. * the date interval pattern is &quot;MMM d - MMM d, yyyy&quot;,
  90. * such as &quot;Jan 10 - Feb 10, 2007&quot;.
  91. * If the largest different calendar field between date1 and date2 is &quot;day&quot;,
  92. * the date interval pattern is &quot;MMM d-d, yyyy&quot;, such as &quot;Jan 10-20, 2007&quot;.
  93. *
  94. * For date skeleton, the interval patterns when year, or month, or date is
  95. * different are defined in resource files.
  96. * For time skeleton, the interval patterns when am/pm, or hour, or minute is
  97. * different are defined in resource files.
  98. *
  99. *
  100. * <P>
  101. * There are 2 dates in interval pattern. For most locales, the first date
  102. * in an interval pattern is the earlier date. There might be a locale in which
  103. * the first date in an interval pattern is the later date.
  104. * We use fallback format for the default order for the locale.
  105. * For example, if the fallback format is &quot;{0} - {1}&quot;, it means
  106. * the first date in the interval pattern for this locale is earlier date.
  107. * If the fallback format is &quot;{1} - {0}&quot;, it means the first date is the
  108. * later date.
  109. * For a particular interval pattern, the default order can be overridden
  110. * by prefixing &quot;latestFirst:&quot; or &quot;earliestFirst:&quot; to the interval pattern.
  111. * For example, if the fallback format is &quot;{0}-{1}&quot;,
  112. * but for skeleton &quot;yMMMd&quot;, the interval pattern when day is different is
  113. * &quot;latestFirst:d-d MMM yy&quot;, it means by default, the first date in interval
  114. * pattern is the earlier date. But for skeleton &quot;yMMMd&quot;, when day is different,
  115. * the first date in &quot;d-d MMM yy&quot; is the later date.
  116. *
  117. * <P>
  118. * The recommended way to create a DateIntervalFormat object is to pass in
  119. * the locale.
  120. * By using a Locale parameter, the DateIntervalFormat object is
  121. * initialized with the pre-defined interval patterns for a given or
  122. * default locale.
  123. * <P>
  124. * Users can also create DateIntervalFormat object
  125. * by supplying their own interval patterns.
  126. * It provides flexibility for power users.
  127. *
  128. * <P>
  129. * After a DateIntervalInfo object is created, clients may modify
  130. * the interval patterns using setIntervalPattern function as so desired.
  131. * Currently, users can only set interval patterns when the following
  132. * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH,
  133. * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, MINUTE, SECOND, and MILLISECOND.
  134. * Interval patterns when other calendar fields are different is not supported.
  135. * <P>
  136. * DateIntervalInfo objects are cloneable.
  137. * When clients obtain a DateIntervalInfo object,
  138. * they can feel free to modify it as necessary.
  139. * <P>
  140. * DateIntervalInfo are not expected to be subclassed.
  141. * Data for a calendar is loaded out of resource bundles.
  142. * Through ICU 4.4, date interval patterns are only supported in the Gregorian
  143. * calendar; non-Gregorian calendars are supported from ICU 4.4.1.
  144. * @stable ICU 4.0
  145. **/
  146. class U_I18N_API DateIntervalInfo final : public UObject {
  147. public:
  148. /**
  149. * Default constructor.
  150. * It does not initialize any interval patterns except
  151. * that it initialize default fall-back pattern as "{0} - {1}",
  152. * which can be reset by setFallbackIntervalPattern().
  153. * It should be followed by setFallbackIntervalPattern() and
  154. * setIntervalPattern(),
  155. * and is recommended to be used only for power users who
  156. * wants to create their own interval patterns and use them to create
  157. * date interval formatter.
  158. * @param status output param set to success/failure code on exit
  159. * @internal ICU 4.0
  160. */
  161. DateIntervalInfo(UErrorCode& status);
  162. /**
  163. * Construct DateIntervalInfo for the given locale,
  164. * @param locale the interval patterns are loaded from the appropriate calendar
  165. * data (specified calendar or default calendar) in this locale.
  166. * @param status output param set to success/failure code on exit
  167. * @stable ICU 4.0
  168. */
  169. DateIntervalInfo(const Locale& locale, UErrorCode& status);
  170. /**
  171. * Copy constructor.
  172. * @stable ICU 4.0
  173. */
  174. DateIntervalInfo(const DateIntervalInfo&);
  175. /**
  176. * Assignment operator
  177. * @stable ICU 4.0
  178. */
  179. DateIntervalInfo& operator=(const DateIntervalInfo&);
  180. /**
  181. * Clone this object polymorphically.
  182. * The caller owns the result and should delete it when done.
  183. * @return a copy of the object
  184. * @stable ICU 4.0
  185. */
  186. virtual DateIntervalInfo* clone() const;
  187. /**
  188. * Destructor.
  189. * It is virtual to be safe, but it is not designed to be subclassed.
  190. * @stable ICU 4.0
  191. */
  192. virtual ~DateIntervalInfo();
  193. /**
  194. * Return true if another object is semantically equal to this one.
  195. *
  196. * @param other the DateIntervalInfo object to be compared with.
  197. * @return true if other is semantically equal to this.
  198. * @stable ICU 4.0
  199. */
  200. virtual bool operator==(const DateIntervalInfo& other) const;
  201. /**
  202. * Return true if another object is semantically unequal to this one.
  203. *
  204. * @param other the DateIntervalInfo object to be compared with.
  205. * @return true if other is semantically unequal to this.
  206. * @stable ICU 4.0
  207. */
  208. bool operator!=(const DateIntervalInfo& other) const;
  209. /**
  210. * Provides a way for client to build interval patterns.
  211. * User could construct DateIntervalInfo by providing a list of skeletons
  212. * and their patterns.
  213. * <P>
  214. * For example:
  215. * <pre>
  216. * UErrorCode status = U_ZERO_ERROR;
  217. * DateIntervalInfo dIntervalInfo = new DateIntervalInfo();
  218. * dIntervalInfo->setFallbackIntervalPattern("{0} ~ {1}");
  219. * dIntervalInfo->setIntervalPattern("yMd", UCAL_YEAR, "'from' yyyy-M-d 'to' yyyy-M-d", status);
  220. * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_MONTH, "'from' yyyy MMM d 'to' MMM d", status);
  221. * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_DAY, "yyyy MMM d-d", status, status);
  222. * </pre>
  223. *
  224. * Restriction:
  225. * Currently, users can only set interval patterns when the following
  226. * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH,
  227. * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, MINUTE, SECOND and MILLISECOND.
  228. * Interval patterns when other calendar fields are different are
  229. * not supported.
  230. *
  231. * @param skeleton the skeleton on which interval pattern based
  232. * @param lrgDiffCalUnit the largest different calendar unit.
  233. * @param intervalPattern the interval pattern on the largest different
  234. * calendar unit.
  235. * For example, if lrgDiffCalUnit is
  236. * "year", the interval pattern for en_US when year
  237. * is different could be "'from' yyyy 'to' yyyy".
  238. * @param status output param set to success/failure code on exit
  239. * @stable ICU 4.0
  240. */
  241. void setIntervalPattern(const UnicodeString& skeleton,
  242. UCalendarDateFields lrgDiffCalUnit,
  243. const UnicodeString& intervalPattern,
  244. UErrorCode& status);
  245. /**
  246. * Get the interval pattern given skeleton and
  247. * the largest different calendar field.
  248. * @param skeleton the skeleton
  249. * @param field the largest different calendar field
  250. * @param result output param to receive the pattern
  251. * @param status output param set to success/failure code on exit
  252. * @return a reference to 'result'
  253. * @stable ICU 4.0
  254. */
  255. UnicodeString& getIntervalPattern(const UnicodeString& skeleton,
  256. UCalendarDateFields field,
  257. UnicodeString& result,
  258. UErrorCode& status) const;
  259. /**
  260. * Get the fallback interval pattern.
  261. * @param result output param to receive the pattern
  262. * @return a reference to 'result'
  263. * @stable ICU 4.0
  264. */
  265. UnicodeString& getFallbackIntervalPattern(UnicodeString& result) const;
  266. /**
  267. * Re-set the fallback interval pattern.
  268. *
  269. * In construction, default fallback pattern is set as "{0} - {1}".
  270. * And constructor taking locale as parameter will set the
  271. * fallback pattern as what defined in the locale resource file.
  272. *
  273. * This method provides a way for user to replace the fallback pattern.
  274. *
  275. * @param fallbackPattern fall-back interval pattern.
  276. * @param status output param set to success/failure code on exit
  277. * @stable ICU 4.0
  278. */
  279. void setFallbackIntervalPattern(const UnicodeString& fallbackPattern,
  280. UErrorCode& status);
  281. /** Get default order -- whether the first date in pattern is later date
  282. or not.
  283. * return default date ordering in interval pattern. true if the first date
  284. * in pattern is later date, false otherwise.
  285. * @stable ICU 4.0
  286. */
  287. UBool getDefaultOrder() const;
  288. /**
  289. * ICU "poor man's RTTI", returns a UClassID for the actual class.
  290. *
  291. * @stable ICU 4.0
  292. */
  293. virtual UClassID getDynamicClassID() const override;
  294. /**
  295. * ICU "poor man's RTTI", returns a UClassID for this class.
  296. *
  297. * @stable ICU 4.0
  298. */
  299. static UClassID U_EXPORT2 getStaticClassID();
  300. private:
  301. /**
  302. * DateIntervalFormat will need access to
  303. * getBestSkeleton(), parseSkeleton(), enum IntervalPatternIndex,
  304. * and calendarFieldToPatternIndex().
  305. *
  306. * Instead of making above public,
  307. * make DateIntervalFormat a friend of DateIntervalInfo.
  308. */
  309. friend class DateIntervalFormat;
  310. /**
  311. * Internal struct used to load resource bundle data.
  312. */
  313. struct U_HIDDEN DateIntervalSink;
  314. /**
  315. * Following is for saving the interval patterns.
  316. * We only support interval patterns on
  317. * ERA, YEAR, MONTH, DAY, AM_PM, HOUR, MINUTE, SECOND and MILLISECOND.
  318. */
  319. enum IntervalPatternIndex
  320. {
  321. kIPI_ERA,
  322. kIPI_YEAR,
  323. kIPI_MONTH,
  324. kIPI_DATE,
  325. kIPI_AM_PM,
  326. kIPI_HOUR,
  327. kIPI_MINUTE,
  328. kIPI_SECOND,
  329. kIPI_MILLISECOND,
  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 functionality 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, MINUTE, SECOND, and MILLISECOND.
  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 bool
  453. DateIntervalInfo::operator!=(const DateIntervalInfo& other) const {
  454. return !operator==(other);
  455. }
  456. U_NAMESPACE_END
  457. #endif
  458. #endif /* U_SHOW_CPLUSPLUS_API */
  459. #endif