intl/icu/source/i18n/unicode/dtitvinf.h

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

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

mercurial