1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/unicode/dtitvinf.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,514 @@ 1.4 +/* 1.5 + ******************************************************************************* 1.6 + * Copyright (C) 2008-2011,2013, International Business Machines Corporation and 1.7 + * others. All Rights Reserved. 1.8 + ******************************************************************************* 1.9 + * 1.10 + * File DTITVINF.H 1.11 + * 1.12 + ******************************************************************************* 1.13 + */ 1.14 + 1.15 +#ifndef __DTITVINF_H__ 1.16 +#define __DTITVINF_H__ 1.17 + 1.18 +#include "unicode/utypes.h" 1.19 + 1.20 +/** 1.21 + * \file 1.22 + * \brief C++ API: Date/Time interval patterns for formatting date/time interval 1.23 + */ 1.24 + 1.25 +#if !UCONFIG_NO_FORMATTING 1.26 + 1.27 +#include "unicode/udat.h" 1.28 +#include "unicode/locid.h" 1.29 +#include "unicode/ucal.h" 1.30 +#include "unicode/dtptngen.h" 1.31 + 1.32 +U_NAMESPACE_BEGIN 1.33 + 1.34 +/** 1.35 + * DateIntervalInfo is a public class for encapsulating localizable 1.36 + * date time interval patterns. It is used by DateIntervalFormat. 1.37 + * 1.38 + * <P> 1.39 + * For most users, ordinary use of DateIntervalFormat does not need to create 1.40 + * DateIntervalInfo object directly. 1.41 + * DateIntervalFormat will take care of it when creating a date interval 1.42 + * formatter when user pass in skeleton and locale. 1.43 + * 1.44 + * <P> 1.45 + * For power users, who want to create their own date interval patterns, 1.46 + * or want to re-set date interval patterns, they could do so by 1.47 + * directly creating DateIntervalInfo and manupulating it. 1.48 + * 1.49 + * <P> 1.50 + * Logically, the interval patterns are mappings 1.51 + * from (skeleton, the_largest_different_calendar_field) 1.52 + * to (date_interval_pattern). 1.53 + * 1.54 + * <P> 1.55 + * A skeleton 1.56 + * <ol> 1.57 + * <li> 1.58 + * only keeps the field pattern letter and ignores all other parts 1.59 + * in a pattern, such as space, punctuations, and string literals. 1.60 + * <li> 1.61 + * hides the order of fields. 1.62 + * <li> 1.63 + * might hide a field's pattern letter length. 1.64 + * 1.65 + * For those non-digit calendar fields, the pattern letter length is 1.66 + * important, such as MMM, MMMM, and MMMMM; EEE and EEEE, 1.67 + * and the field's pattern letter length is honored. 1.68 + * 1.69 + * For the digit calendar fields, such as M or MM, d or dd, yy or yyyy, 1.70 + * the field pattern length is ignored and the best match, which is defined 1.71 + * in date time patterns, will be returned without honor the field pattern 1.72 + * letter length in skeleton. 1.73 + * </ol> 1.74 + * 1.75 + * <P> 1.76 + * The calendar fields we support for interval formatting are: 1.77 + * year, month, date, day-of-week, am-pm, hour, hour-of-day, and minute. 1.78 + * Those calendar fields can be defined in the following order: 1.79 + * year > month > date > am-pm > hour > minute 1.80 + * 1.81 + * The largest different calendar fields between 2 calendars is the 1.82 + * first different calendar field in above order. 1.83 + * 1.84 + * For example: the largest different calendar fields between "Jan 10, 2007" 1.85 + * and "Feb 20, 2008" is year. 1.86 + * 1.87 + * <P> 1.88 + * There is a set of pre-defined static skeleton strings. 1.89 + * There are pre-defined interval patterns for those pre-defined skeletons 1.90 + * in locales' resource files. 1.91 + * For example, for a skeleton UDAT_YEAR_ABBR_MONTH_DAY, which is "yMMMd", 1.92 + * in en_US, if the largest different calendar field between date1 and date2 1.93 + * is "year", the date interval pattern is "MMM d, yyyy - MMM d, yyyy", 1.94 + * such as "Jan 10, 2007 - Jan 10, 2008". 1.95 + * If the largest different calendar field between date1 and date2 is "month", 1.96 + * the date interval pattern is "MMM d - MMM d, yyyy", 1.97 + * such as "Jan 10 - Feb 10, 2007". 1.98 + * If the largest different calendar field between date1 and date2 is "day", 1.99 + * the date interval pattern is "MMM d-d, yyyy", such as "Jan 10-20, 2007". 1.100 + * 1.101 + * For date skeleton, the interval patterns when year, or month, or date is 1.102 + * different are defined in resource files. 1.103 + * For time skeleton, the interval patterns when am/pm, or hour, or minute is 1.104 + * different are defined in resource files. 1.105 + * 1.106 + * 1.107 + * <P> 1.108 + * There are 2 dates in interval pattern. For most locales, the first date 1.109 + * in an interval pattern is the earlier date. There might be a locale in which 1.110 + * the first date in an interval pattern is the later date. 1.111 + * We use fallback format for the default order for the locale. 1.112 + * For example, if the fallback format is "{0} - {1}", it means 1.113 + * the first date in the interval pattern for this locale is earlier date. 1.114 + * If the fallback format is "{1} - {0}", it means the first date is the 1.115 + * later date. 1.116 + * For a particular interval pattern, the default order can be overriden 1.117 + * by prefixing "latestFirst:" or "earliestFirst:" to the interval pattern. 1.118 + * For example, if the fallback format is "{0}-{1}", 1.119 + * but for skeleton "yMMMd", the interval pattern when day is different is 1.120 + * "latestFirst:d-d MMM yy", it means by default, the first date in interval 1.121 + * pattern is the earlier date. But for skeleton "yMMMd", when day is different, 1.122 + * the first date in "d-d MMM yy" is the later date. 1.123 + * 1.124 + * <P> 1.125 + * The recommended way to create a DateIntervalFormat object is to pass in 1.126 + * the locale. 1.127 + * By using a Locale parameter, the DateIntervalFormat object is 1.128 + * initialized with the pre-defined interval patterns for a given or 1.129 + * default locale. 1.130 + * <P> 1.131 + * Users can also create DateIntervalFormat object 1.132 + * by supplying their own interval patterns. 1.133 + * It provides flexibility for power users. 1.134 + * 1.135 + * <P> 1.136 + * After a DateIntervalInfo object is created, clients may modify 1.137 + * the interval patterns using setIntervalPattern function as so desired. 1.138 + * Currently, users can only set interval patterns when the following 1.139 + * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, 1.140 + * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, and MINUTE. 1.141 + * Interval patterns when other calendar fields are different is not supported. 1.142 + * <P> 1.143 + * DateIntervalInfo objects are cloneable. 1.144 + * When clients obtain a DateIntervalInfo object, 1.145 + * they can feel free to modify it as necessary. 1.146 + * <P> 1.147 + * DateIntervalInfo are not expected to be subclassed. 1.148 + * Data for a calendar is loaded out of resource bundles. 1.149 + * Through ICU 4.4, date interval patterns are only supported in the Gregorian 1.150 + * calendar; non-Gregorian calendars are supported from ICU 4.4.1. 1.151 + * @stable ICU 4.0 1.152 +**/ 1.153 + 1.154 +class U_I18N_API DateIntervalInfo : public UObject { 1.155 +public: 1.156 +#ifndef U_HIDE_INTERNAL_API 1.157 + /** 1.158 + * Default constructor. 1.159 + * It does not initialize any interval patterns except 1.160 + * that it initialize default fall-back pattern as "{0} - {1}", 1.161 + * which can be reset by setFallbackIntervalPattern(). 1.162 + * It should be followed by setFallbackIntervalPattern() and 1.163 + * setIntervalPattern(), 1.164 + * and is recommended to be used only for power users who 1.165 + * wants to create their own interval patterns and use them to create 1.166 + * date interval formatter. 1.167 + * @param status output param set to success/failure code on exit 1.168 + * @internal ICU 4.0 1.169 + */ 1.170 + DateIntervalInfo(UErrorCode& status); 1.171 +#endif /* U_HIDE_INTERNAL_API */ 1.172 + 1.173 + 1.174 + /** 1.175 + * Construct DateIntervalInfo for the given locale, 1.176 + * @param locale the interval patterns are loaded from the appropriate calendar 1.177 + * data (specified calendar or default calendar) in this locale. 1.178 + * @param status output param set to success/failure code on exit 1.179 + * @stable ICU 4.0 1.180 + */ 1.181 + DateIntervalInfo(const Locale& locale, UErrorCode& status); 1.182 + 1.183 + 1.184 + /** 1.185 + * Copy constructor. 1.186 + * @stable ICU 4.0 1.187 + */ 1.188 + DateIntervalInfo(const DateIntervalInfo&); 1.189 + 1.190 + /** 1.191 + * Assignment operator 1.192 + * @stable ICU 4.0 1.193 + */ 1.194 + DateIntervalInfo& operator=(const DateIntervalInfo&); 1.195 + 1.196 + /** 1.197 + * Clone this object polymorphically. 1.198 + * The caller owns the result and should delete it when done. 1.199 + * @return a copy of the object 1.200 + * @stable ICU 4.0 1.201 + */ 1.202 + virtual DateIntervalInfo* clone(void) const; 1.203 + 1.204 + /** 1.205 + * Destructor. 1.206 + * It is virtual to be safe, but it is not designed to be subclassed. 1.207 + * @stable ICU 4.0 1.208 + */ 1.209 + virtual ~DateIntervalInfo(); 1.210 + 1.211 + 1.212 + /** 1.213 + * Return true if another object is semantically equal to this one. 1.214 + * 1.215 + * @param other the DateIntervalInfo object to be compared with. 1.216 + * @return true if other is semantically equal to this. 1.217 + * @stable ICU 4.0 1.218 + */ 1.219 + virtual UBool operator==(const DateIntervalInfo& other) const; 1.220 + 1.221 + /** 1.222 + * Return true if another object is semantically unequal to this one. 1.223 + * 1.224 + * @param other the DateIntervalInfo object to be compared with. 1.225 + * @return true if other is semantically unequal to this. 1.226 + * @stable ICU 4.0 1.227 + */ 1.228 + UBool operator!=(const DateIntervalInfo& other) const; 1.229 + 1.230 + 1.231 + 1.232 + /** 1.233 + * Provides a way for client to build interval patterns. 1.234 + * User could construct DateIntervalInfo by providing a list of skeletons 1.235 + * and their patterns. 1.236 + * <P> 1.237 + * For example: 1.238 + * <pre> 1.239 + * UErrorCode status = U_ZERO_ERROR; 1.240 + * DateIntervalInfo dIntervalInfo = new DateIntervalInfo(); 1.241 + * dIntervalInfo->setFallbackIntervalPattern("{0} ~ {1}"); 1.242 + * dIntervalInfo->setIntervalPattern("yMd", UCAL_YEAR, "'from' yyyy-M-d 'to' yyyy-M-d", status); 1.243 + * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_MONTH, "'from' yyyy MMM d 'to' MMM d", status); 1.244 + * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_DAY, "yyyy MMM d-d", status, status); 1.245 + * </pre> 1.246 + * 1.247 + * Restriction: 1.248 + * Currently, users can only set interval patterns when the following 1.249 + * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, 1.250 + * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, and MINUTE. 1.251 + * Interval patterns when other calendar fields are different are 1.252 + * not supported. 1.253 + * 1.254 + * @param skeleton the skeleton on which interval pattern based 1.255 + * @param lrgDiffCalUnit the largest different calendar unit. 1.256 + * @param intervalPattern the interval pattern on the largest different 1.257 + * calendar unit. 1.258 + * For example, if lrgDiffCalUnit is 1.259 + * "year", the interval pattern for en_US when year 1.260 + * is different could be "'from' yyyy 'to' yyyy". 1.261 + * @param status output param set to success/failure code on exit 1.262 + * @stable ICU 4.0 1.263 + */ 1.264 + void setIntervalPattern(const UnicodeString& skeleton, 1.265 + UCalendarDateFields lrgDiffCalUnit, 1.266 + const UnicodeString& intervalPattern, 1.267 + UErrorCode& status); 1.268 + 1.269 + /** 1.270 + * Get the interval pattern given skeleton and 1.271 + * the largest different calendar field. 1.272 + * @param skeleton the skeleton 1.273 + * @param field the largest different calendar field 1.274 + * @param result output param to receive the pattern 1.275 + * @param status output param set to success/failure code on exit 1.276 + * @return a reference to 'result' 1.277 + * @stable ICU 4.0 1.278 + */ 1.279 + UnicodeString& getIntervalPattern(const UnicodeString& skeleton, 1.280 + UCalendarDateFields field, 1.281 + UnicodeString& result, 1.282 + UErrorCode& status) const; 1.283 + 1.284 + /** 1.285 + * Get the fallback interval pattern. 1.286 + * @param result output param to receive the pattern 1.287 + * @return a reference to 'result' 1.288 + * @stable ICU 4.0 1.289 + */ 1.290 + UnicodeString& getFallbackIntervalPattern(UnicodeString& result) const; 1.291 + 1.292 + 1.293 + /** 1.294 + * Re-set the fallback interval pattern. 1.295 + * 1.296 + * In construction, default fallback pattern is set as "{0} - {1}". 1.297 + * And constructor taking locale as parameter will set the 1.298 + * fallback pattern as what defined in the locale resource file. 1.299 + * 1.300 + * This method provides a way for user to replace the fallback pattern. 1.301 + * 1.302 + * @param fallbackPattern fall-back interval pattern. 1.303 + * @param status output param set to success/failure code on exit 1.304 + * @stable ICU 4.0 1.305 + */ 1.306 + void setFallbackIntervalPattern(const UnicodeString& fallbackPattern, 1.307 + UErrorCode& status); 1.308 + 1.309 + 1.310 + /** Get default order -- whether the first date in pattern is later date 1.311 + or not. 1.312 + * return default date ordering in interval pattern. TRUE if the first date 1.313 + * in pattern is later date, FALSE otherwise. 1.314 + * @stable ICU 4.0 1.315 + */ 1.316 + UBool getDefaultOrder() const; 1.317 + 1.318 + 1.319 + /** 1.320 + * ICU "poor man's RTTI", returns a UClassID for the actual class. 1.321 + * 1.322 + * @stable ICU 4.0 1.323 + */ 1.324 + virtual UClassID getDynamicClassID() const; 1.325 + 1.326 + /** 1.327 + * ICU "poor man's RTTI", returns a UClassID for this class. 1.328 + * 1.329 + * @stable ICU 4.0 1.330 + */ 1.331 + static UClassID U_EXPORT2 getStaticClassID(); 1.332 + 1.333 + 1.334 +private: 1.335 + /** 1.336 + * DateIntervalFormat will need access to 1.337 + * getBestSkeleton(), parseSkeleton(), enum IntervalPatternIndex, 1.338 + * and calendarFieldToPatternIndex(). 1.339 + * 1.340 + * Instead of making above public, 1.341 + * make DateIntervalFormat a friend of DateIntervalInfo. 1.342 + */ 1.343 + friend class DateIntervalFormat; 1.344 + 1.345 + /** 1.346 + * Following is for saving the interval patterns. 1.347 + * We only support interval patterns on 1.348 + * ERA, YEAR, MONTH, DAY, AM_PM, HOUR, and MINUTE 1.349 + */ 1.350 + enum IntervalPatternIndex 1.351 + { 1.352 + kIPI_ERA, 1.353 + kIPI_YEAR, 1.354 + kIPI_MONTH, 1.355 + kIPI_DATE, 1.356 + kIPI_AM_PM, 1.357 + kIPI_HOUR, 1.358 + kIPI_MINUTE, 1.359 + kIPI_MAX_INDEX 1.360 + }; 1.361 +public: 1.362 +#ifndef U_HIDE_INTERNAL_API 1.363 + /** 1.364 + * Max index for stored interval patterns 1.365 + * @internal ICU 4.4 1.366 + */ 1.367 + enum { 1.368 + kMaxIntervalPatternIndex = kIPI_MAX_INDEX 1.369 + }; 1.370 +#endif /* U_HIDE_INTERNAL_API */ 1.371 +private: 1.372 + 1.373 + 1.374 + /** 1.375 + * Initialize the DateIntervalInfo from locale 1.376 + * @param locale the given locale. 1.377 + * @param status output param set to success/failure code on exit 1.378 + */ 1.379 + void initializeData(const Locale& locale, UErrorCode& status); 1.380 + 1.381 + 1.382 + /* Set Interval pattern. 1.383 + * 1.384 + * It sets interval pattern into the hash map. 1.385 + * 1.386 + * @param skeleton skeleton on which the interval pattern based 1.387 + * @param lrgDiffCalUnit the largest different calendar unit. 1.388 + * @param intervalPattern the interval pattern on the largest different 1.389 + * calendar unit. 1.390 + * @param status output param set to success/failure code on exit 1.391 + */ 1.392 + void setIntervalPatternInternally(const UnicodeString& skeleton, 1.393 + UCalendarDateFields lrgDiffCalUnit, 1.394 + const UnicodeString& intervalPattern, 1.395 + UErrorCode& status); 1.396 + 1.397 + 1.398 + /**given an input skeleton, get the best match skeleton 1.399 + * which has pre-defined interval pattern in resource file. 1.400 + * Also return the difference between the input skeleton 1.401 + * and the best match skeleton. 1.402 + * 1.403 + * TODO (xji): set field weight or 1.404 + * isolate the funtionality in DateTimePatternGenerator 1.405 + * @param skeleton input skeleton 1.406 + * @param bestMatchDistanceInfo the difference between input skeleton 1.407 + * and best match skeleton. 1.408 + * 0, if there is exact match for input skeleton 1.409 + * 1, if there is only field width difference between 1.410 + * the best match and the input skeleton 1.411 + * 2, the only field difference is 'v' and 'z' 1.412 + * -1, if there is calendar field difference between 1.413 + * the best match and the input skeleton 1.414 + * @return best match skeleton 1.415 + */ 1.416 + const UnicodeString* getBestSkeleton(const UnicodeString& skeleton, 1.417 + int8_t& bestMatchDistanceInfo) const; 1.418 + 1.419 + 1.420 + /** 1.421 + * Parse skeleton, save each field's width. 1.422 + * It is used for looking for best match skeleton, 1.423 + * and adjust pattern field width. 1.424 + * @param skeleton skeleton to be parsed 1.425 + * @param skeletonFieldWidth parsed skeleton field width 1.426 + */ 1.427 + static void U_EXPORT2 parseSkeleton(const UnicodeString& skeleton, 1.428 + int32_t* skeletonFieldWidth); 1.429 + 1.430 + 1.431 + /** 1.432 + * Check whether one field width is numeric while the other is string. 1.433 + * 1.434 + * TODO (xji): make it general 1.435 + * 1.436 + * @param fieldWidth one field width 1.437 + * @param anotherFieldWidth another field width 1.438 + * @param patternLetter pattern letter char 1.439 + * @return true if one field width is numeric and the other is string, 1.440 + * false otherwise. 1.441 + */ 1.442 + static UBool U_EXPORT2 stringNumeric(int32_t fieldWidth, 1.443 + int32_t anotherFieldWidth, 1.444 + char patternLetter); 1.445 + 1.446 + 1.447 + /** 1.448 + * Convert calendar field to the interval pattern index in 1.449 + * hash table. 1.450 + * 1.451 + * Since we only support the following calendar fields: 1.452 + * ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, DAY_OF_WEEK, 1.453 + * AM_PM, HOUR, HOUR_OF_DAY, and MINUTE, 1.454 + * We reserve only 4 interval patterns for a skeleton. 1.455 + * 1.456 + * @param field calendar field 1.457 + * @param status output param set to success/failure code on exit 1.458 + * @return interval pattern index in hash table 1.459 + */ 1.460 + static IntervalPatternIndex U_EXPORT2 calendarFieldToIntervalIndex( 1.461 + UCalendarDateFields field, 1.462 + UErrorCode& status); 1.463 + 1.464 + 1.465 + /** 1.466 + * delete hash table (of type fIntervalPatterns). 1.467 + * 1.468 + * @param hTable hash table to be deleted 1.469 + */ 1.470 + void deleteHash(Hashtable* hTable); 1.471 + 1.472 + 1.473 + /** 1.474 + * initialize hash table (of type fIntervalPatterns). 1.475 + * 1.476 + * @param status output param set to success/failure code on exit 1.477 + * @return hash table initialized 1.478 + */ 1.479 + Hashtable* initHash(UErrorCode& status); 1.480 + 1.481 + 1.482 + 1.483 + /** 1.484 + * copy hash table (of type fIntervalPatterns). 1.485 + * 1.486 + * @param source the source to copy from 1.487 + * @param target the target to copy to 1.488 + * @param status output param set to success/failure code on exit 1.489 + */ 1.490 + void copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status); 1.491 + 1.492 + 1.493 + // data members 1.494 + // fallback interval pattern 1.495 + UnicodeString fFallbackIntervalPattern; 1.496 + // default order 1.497 + UBool fFirstDateInPtnIsLaterDate; 1.498 + 1.499 + // HashMap<UnicodeString, UnicodeString[kIPI_MAX_INDEX]> 1.500 + // HashMap( skeleton, pattern[largest_different_field] ) 1.501 + Hashtable* fIntervalPatterns; 1.502 + 1.503 +};// end class DateIntervalInfo 1.504 + 1.505 + 1.506 +inline UBool 1.507 +DateIntervalInfo::operator!=(const DateIntervalInfo& other) const { 1.508 + return !operator==(other); 1.509 +} 1.510 + 1.511 + 1.512 +U_NAMESPACE_END 1.513 + 1.514 +#endif 1.515 + 1.516 +#endif 1.517 +