Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:04

0001 // © 2016 and later: Unicode, Inc. and others.
0002 // License & terms of use: http://www.unicode.org/copyright.html
0003 /*
0004  *******************************************************************************
0005  * Copyright (C) 2008-2016, International Business Machines Corporation and
0006  * others. All Rights Reserved.
0007  *******************************************************************************
0008  *
0009  * File DTITVINF.H
0010  *
0011  *******************************************************************************
0012  */
0013 
0014 #ifndef __DTITVINF_H__
0015 #define __DTITVINF_H__
0016 
0017 #include "unicode/utypes.h"
0018 
0019 #if U_SHOW_CPLUSPLUS_API
0020 
0021 /**
0022  * \file
0023  * \brief C++ API: Date/Time interval patterns for formatting date/time interval
0024  */
0025 
0026 #if !UCONFIG_NO_FORMATTING
0027 
0028 #include "unicode/udat.h"
0029 #include "unicode/locid.h"
0030 #include "unicode/ucal.h"
0031 #include "unicode/dtptngen.h"
0032 
0033 U_NAMESPACE_BEGIN
0034 
0035 /**
0036  * DateIntervalInfo is a public class for encapsulating localizable
0037  * date time interval patterns. It is used by DateIntervalFormat.
0038  *
0039  * <P>
0040  * For most users, ordinary use of DateIntervalFormat does not need to create
0041  * DateIntervalInfo object directly.
0042  * DateIntervalFormat will take care of it when creating a date interval
0043  * formatter when user pass in skeleton and locale.
0044  *
0045  * <P>
0046  * For power users, who want to create their own date interval patterns,
0047  * or want to re-set date interval patterns, they could do so by
0048  * directly creating DateIntervalInfo and manipulating it.
0049  *
0050  * <P>
0051  * Logically, the interval patterns are mappings
0052  * from (skeleton, the_largest_different_calendar_field)
0053  * to (date_interval_pattern).
0054  *
0055  * <P>
0056  * A skeleton
0057  * <ol>
0058  * <li>
0059  * only keeps the field pattern letter and ignores all other parts
0060  * in a pattern, such as space, punctuations, and string literals.
0061  * <li>
0062  * hides the order of fields.
0063  * <li>
0064  * might hide a field's pattern letter length.
0065  *
0066  * For those non-digit calendar fields, the pattern letter length is
0067  * important, such as MMM, MMMM, and MMMMM; EEE and EEEE,
0068  * and the field's pattern letter length is honored.
0069  *
0070  * For the digit calendar fields,  such as M or MM, d or dd, yy or yyyy,
0071  * the field pattern length is ignored and the best match, which is defined
0072  * in date time patterns, will be returned without honor the field pattern
0073  * letter length in skeleton.
0074  * </ol>
0075  *
0076  * <P>
0077  * The calendar fields we support for interval formatting are:
0078  * year, month, date, day-of-week, am-pm, hour, hour-of-day, and minute.
0079  * Those calendar fields can be defined in the following order:
0080  * year >  month > date > am-pm > hour >  minute
0081  *
0082  * The largest different calendar fields between 2 calendars is the
0083  * first different calendar field in above order.
0084  *
0085  * For example: the largest different calendar fields between &quot;Jan 10, 2007&quot;
0086  * and &quot;Feb 20, 2008&quot; is year.
0087  *
0088  * <P>
0089  * There is a set of pre-defined static skeleton strings.
0090  * There are pre-defined interval patterns for those pre-defined skeletons
0091  * in locales' resource files.
0092  * For example, for a skeleton UDAT_YEAR_ABBR_MONTH_DAY, which is  &quot;yMMMd&quot;,
0093  * in  en_US, if the largest different calendar field between date1 and date2
0094  * is &quot;year&quot;, the date interval pattern  is &quot;MMM d, yyyy - MMM d, yyyy&quot;,
0095  * such as &quot;Jan 10, 2007 - Jan 10, 2008&quot;.
0096  * If the largest different calendar field between date1 and date2 is &quot;month&quot;,
0097  * the date interval pattern is &quot;MMM d - MMM d, yyyy&quot;,
0098  * such as &quot;Jan 10 - Feb 10, 2007&quot;.
0099  * If the largest different calendar field between date1 and date2 is &quot;day&quot;,
0100  * the date interval pattern is &quot;MMM d-d, yyyy&quot;, such as &quot;Jan 10-20, 2007&quot;.
0101  *
0102  * For date skeleton, the interval patterns when year, or month, or date is
0103  * different are defined in resource files.
0104  * For time skeleton, the interval patterns when am/pm, or hour, or minute is
0105  * different are defined in resource files.
0106  *
0107  *
0108  * <P>
0109  * There are 2 dates in interval pattern. For most locales, the first date
0110  * in an interval pattern is the earlier date. There might be a locale in which
0111  * the first date in an interval pattern is the later date.
0112  * We use fallback format for the default order for the locale.
0113  * For example, if the fallback format is &quot;{0} - {1}&quot;, it means
0114  * the first date in the interval pattern for this locale is earlier date.
0115  * If the fallback format is &quot;{1} - {0}&quot;, it means the first date is the
0116  * later date.
0117  * For a particular interval pattern, the default order can be overridden
0118  * by prefixing &quot;latestFirst:&quot; or &quot;earliestFirst:&quot; to the interval pattern.
0119  * For example, if the fallback format is &quot;{0}-{1}&quot;,
0120  * but for skeleton &quot;yMMMd&quot;, the interval pattern when day is different is
0121  * &quot;latestFirst:d-d MMM yy&quot;, it means by default, the first date in interval
0122  * pattern is the earlier date. But for skeleton &quot;yMMMd&quot;, when day is different,
0123  * the first date in &quot;d-d MMM yy&quot; is the later date.
0124  *
0125  * <P>
0126  * The recommended way to create a DateIntervalFormat object is to pass in
0127  * the locale.
0128  * By using a Locale parameter, the DateIntervalFormat object is
0129  * initialized with the pre-defined interval patterns for a given or
0130  * default locale.
0131  * <P>
0132  * Users can also create DateIntervalFormat object
0133  * by supplying their own interval patterns.
0134  * It provides flexibility for power users.
0135  *
0136  * <P>
0137  * After a DateIntervalInfo object is created, clients may modify
0138  * the interval patterns using setIntervalPattern function as so desired.
0139  * Currently, users can only set interval patterns when the following
0140  * calendar fields are different: ERA, YEAR, MONTH, DATE, DAY_OF_MONTH,
0141  * DAY_OF_WEEK, AM_PM, HOUR, HOUR_OF_DAY, MINUTE, SECOND, and MILLISECOND.
0142  * Interval patterns when other calendar fields are different is not supported.
0143  * <P>
0144  * DateIntervalInfo objects are cloneable.
0145  * When clients obtain a DateIntervalInfo object,
0146  * they can feel free to modify it as necessary.
0147  * <P>
0148  * DateIntervalInfo are not expected to be subclassed.
0149  * Data for a calendar is loaded out of resource bundles.
0150  * Through ICU 4.4, date interval patterns are only supported in the Gregorian
0151  * calendar; non-Gregorian calendars are supported from ICU 4.4.1.
0152  * @stable ICU 4.0
0153 **/
0154 class U_I18N_API DateIntervalInfo final : public UObject {
0155 public:
0156     /**
0157      * Default constructor.
0158      * It does not initialize any interval patterns except
0159      * that it initialize default fall-back pattern as "{0} - {1}",
0160      * which can be reset by setFallbackIntervalPattern().
0161      * It should be followed by setFallbackIntervalPattern() and
0162      * setIntervalPattern(),
0163      * and is recommended to be used only for power users who
0164      * wants to create their own interval patterns and use them to create
0165      * date interval formatter.
0166      * @param status   output param set to success/failure code on exit
0167      * @internal ICU 4.0
0168      */
0169     DateIntervalInfo(UErrorCode& status);
0170 
0171 
0172     /**
0173      * Construct DateIntervalInfo for the given locale,
0174      * @param locale  the interval patterns are loaded from the appropriate calendar
0175      *                data (specified calendar or default calendar) in this locale.
0176      * @param status  output param set to success/failure code on exit
0177      * @stable ICU 4.0
0178      */
0179     DateIntervalInfo(const Locale& locale, UErrorCode& status);
0180 
0181 
0182     /**
0183      * Copy constructor.
0184      * @stable ICU 4.0
0185      */
0186     DateIntervalInfo(const DateIntervalInfo&);
0187 
0188     /**
0189      * Assignment operator
0190      * @stable ICU 4.0
0191      */
0192     DateIntervalInfo& operator=(const DateIntervalInfo&);
0193 
0194     /**
0195      * Clone this object polymorphically.
0196      * The caller owns the result and should delete it when done.
0197      * @return   a copy of the object
0198      * @stable ICU 4.0
0199      */
0200     virtual DateIntervalInfo* clone() const;
0201 
0202     /**
0203      * Destructor.
0204      * It is virtual to be safe, but it is not designed to be subclassed.
0205      * @stable ICU 4.0
0206      */
0207     virtual ~DateIntervalInfo();
0208 
0209 
0210     /**
0211      * Return true if another object is semantically equal to this one.
0212      *
0213      * @param other    the DateIntervalInfo object to be compared with.
0214      * @return         true if other is semantically equal to this.
0215      * @stable ICU 4.0
0216      */
0217     virtual bool operator==(const DateIntervalInfo& other) const;
0218 
0219     /**
0220      * Return true if another object is semantically unequal to this one.
0221      *
0222      * @param other    the DateIntervalInfo object to be compared with.
0223      * @return         true if other is semantically unequal to this.
0224      * @stable ICU 4.0
0225      */
0226     bool operator!=(const DateIntervalInfo& other) const;
0227 
0228 
0229 
0230     /**
0231      * Provides a way for client to build interval patterns.
0232      * User could construct DateIntervalInfo by providing a list of skeletons
0233      * and their patterns.
0234      * <P>
0235      * For example:
0236      * <pre>
0237      * UErrorCode status = U_ZERO_ERROR;
0238      * DateIntervalInfo dIntervalInfo = new DateIntervalInfo();
0239      * dIntervalInfo->setFallbackIntervalPattern("{0} ~ {1}");
0240      * dIntervalInfo->setIntervalPattern("yMd", UCAL_YEAR, "'from' yyyy-M-d 'to' yyyy-M-d", status);
0241      * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_MONTH, "'from' yyyy MMM d 'to' MMM d", status);
0242      * dIntervalInfo->setIntervalPattern("yMMMd", UCAL_DAY, "yyyy MMM d-d", status, status);
0243      * </pre>
0244      *
0245      * Restriction:
0246      * Currently, users can only set interval patterns when the following
0247      * calendar fields are different: ERA, YEAR, MONTH, DATE,  DAY_OF_MONTH,
0248      * DAY_OF_WEEK, AM_PM,  HOUR, HOUR_OF_DAY, MINUTE, SECOND and MILLISECOND.
0249      * Interval patterns when other calendar fields are different are
0250      * not supported.
0251      *
0252      * @param skeleton         the skeleton on which interval pattern based
0253      * @param lrgDiffCalUnit   the largest different calendar unit.
0254      * @param intervalPattern  the interval pattern on the largest different
0255      *                         calendar unit.
0256      *                         For example, if lrgDiffCalUnit is
0257      *                         "year", the interval pattern for en_US when year
0258      *                         is different could be "'from' yyyy 'to' yyyy".
0259      * @param status           output param set to success/failure code on exit
0260      * @stable ICU 4.0
0261      */
0262     void setIntervalPattern(const UnicodeString& skeleton,
0263                             UCalendarDateFields lrgDiffCalUnit,
0264                             const UnicodeString& intervalPattern,
0265                             UErrorCode& status);
0266 
0267     /**
0268      * Get the interval pattern given skeleton and
0269      * the largest different calendar field.
0270      * @param skeleton   the skeleton
0271      * @param field      the largest different calendar field
0272      * @param result     output param to receive the pattern
0273      * @param status     output param set to success/failure code on exit
0274      * @return a reference to 'result'
0275      * @stable ICU 4.0
0276      */
0277     UnicodeString& getIntervalPattern(const UnicodeString& skeleton,
0278                                       UCalendarDateFields field,
0279                                       UnicodeString& result,
0280                                       UErrorCode& status) const;
0281 
0282     /**
0283      * Get the fallback interval pattern.
0284      * @param  result   output param to receive the pattern
0285      * @return a reference to 'result'
0286      * @stable ICU 4.0
0287      */
0288     UnicodeString& getFallbackIntervalPattern(UnicodeString& result) const;
0289 
0290 
0291     /**
0292      * Re-set the fallback interval pattern.
0293      *
0294      * In construction, default fallback pattern is set as "{0} - {1}".
0295      * And constructor taking locale as parameter will set the
0296      * fallback pattern as what defined in the locale resource file.
0297      *
0298      * This method provides a way for user to replace the fallback pattern.
0299      *
0300      * @param fallbackPattern  fall-back interval pattern.
0301      * @param status           output param set to success/failure code on exit
0302      * @stable ICU 4.0
0303      */
0304     void setFallbackIntervalPattern(const UnicodeString& fallbackPattern,
0305                                     UErrorCode& status);
0306 
0307 
0308     /** Get default order -- whether the first date in pattern is later date
0309                              or not.
0310      * return default date ordering in interval pattern. true if the first date
0311      *        in pattern is later date, false otherwise.
0312      * @stable ICU 4.0
0313      */
0314     UBool getDefaultOrder() const;
0315 
0316 
0317     /**
0318      * ICU "poor man's RTTI", returns a UClassID for the actual class.
0319      *
0320      * @stable ICU 4.0
0321      */
0322     virtual UClassID getDynamicClassID() const override;
0323 
0324     /**
0325      * ICU "poor man's RTTI", returns a UClassID for this class.
0326      *
0327      * @stable ICU 4.0
0328      */
0329     static UClassID U_EXPORT2 getStaticClassID();
0330 
0331 
0332 private:
0333     /**
0334      * DateIntervalFormat will need access to
0335      * getBestSkeleton(), parseSkeleton(), enum IntervalPatternIndex,
0336      * and calendarFieldToPatternIndex().
0337      *
0338      * Instead of making above public,
0339      * make DateIntervalFormat a friend of DateIntervalInfo.
0340      */
0341     friend class DateIntervalFormat;
0342 
0343     /**
0344      * Internal struct used to load resource bundle data.
0345      */
0346     struct U_HIDDEN DateIntervalSink;
0347 
0348     /**
0349      * Following is for saving the interval patterns.
0350      * We only support interval patterns on
0351      * ERA, YEAR, MONTH, DAY, AM_PM, HOUR, MINUTE, SECOND and MILLISECOND.
0352      */
0353     enum IntervalPatternIndex
0354     {
0355         kIPI_ERA,
0356         kIPI_YEAR,
0357         kIPI_MONTH,
0358         kIPI_DATE,
0359         kIPI_AM_PM,
0360         kIPI_HOUR,
0361         kIPI_MINUTE,
0362         kIPI_SECOND,
0363         kIPI_MILLISECOND,
0364         kIPI_MAX_INDEX
0365     };
0366 public:
0367 #ifndef U_HIDE_INTERNAL_API
0368     /**
0369      * Max index for stored interval patterns
0370      * @internal ICU 4.4
0371      */
0372      enum {
0373          kMaxIntervalPatternIndex = kIPI_MAX_INDEX
0374      };
0375 #endif  /* U_HIDE_INTERNAL_API */
0376 private:
0377 
0378 
0379     /**
0380      * Initialize the DateIntervalInfo from locale
0381      * @param locale   the given locale.
0382      * @param status   output param set to success/failure code on exit
0383      */
0384     void initializeData(const Locale& locale, UErrorCode& status);
0385 
0386 
0387     /* Set Interval pattern.
0388      *
0389      * It sets interval pattern into the hash map.
0390      *
0391      * @param skeleton         skeleton on which the interval pattern based
0392      * @param lrgDiffCalUnit   the largest different calendar unit.
0393      * @param intervalPattern  the interval pattern on the largest different
0394      *                         calendar unit.
0395      * @param status           output param set to success/failure code on exit
0396      */
0397     void setIntervalPatternInternally(const UnicodeString& skeleton,
0398                                       UCalendarDateFields lrgDiffCalUnit,
0399                                       const UnicodeString& intervalPattern,
0400                                       UErrorCode& status);
0401 
0402 
0403     /**given an input skeleton, get the best match skeleton
0404      * which has pre-defined interval pattern in resource file.
0405      * Also return the difference between the input skeleton
0406      * and the best match skeleton.
0407      *
0408      * TODO (xji): set field weight or
0409      *             isolate the functionality in DateTimePatternGenerator
0410      * @param  skeleton               input skeleton
0411      * @param  bestMatchDistanceInfo  the difference between input skeleton
0412      *                                and best match skeleton.
0413      *         0, if there is exact match for input skeleton
0414      *         1, if there is only field width difference between
0415      *            the best match and the input skeleton
0416      *         2, the only field difference is 'v' and 'z'
0417      *        -1, if there is calendar field difference between
0418      *            the best match and the input skeleton
0419      * @return                        best match skeleton
0420      */
0421     const UnicodeString* getBestSkeleton(const UnicodeString& skeleton,
0422                                          int8_t& bestMatchDistanceInfo) const;
0423 
0424 
0425     /**
0426      * Parse skeleton, save each field's width.
0427      * It is used for looking for best match skeleton,
0428      * and adjust pattern field width.
0429      * @param skeleton            skeleton to be parsed
0430      * @param skeletonFieldWidth  parsed skeleton field width
0431      */
0432     static void U_EXPORT2 parseSkeleton(const UnicodeString& skeleton,
0433                                         int32_t* skeletonFieldWidth);
0434 
0435 
0436     /**
0437      * Check whether one field width is numeric while the other is string.
0438      *
0439      * TODO (xji): make it general
0440      *
0441      * @param fieldWidth          one field width
0442      * @param anotherFieldWidth   another field width
0443      * @param patternLetter       pattern letter char
0444      * @return true if one field width is numeric and the other is string,
0445      *         false otherwise.
0446      */
0447     static UBool U_EXPORT2 stringNumeric(int32_t fieldWidth,
0448                                          int32_t anotherFieldWidth,
0449                                          char patternLetter);
0450 
0451 
0452     /**
0453      * Convert calendar field to the interval pattern index in
0454      * hash table.
0455      *
0456      * Since we only support the following calendar fields:
0457      * ERA, YEAR, MONTH, DATE, DAY_OF_MONTH, DAY_OF_WEEK,
0458      * AM_PM, HOUR, HOUR_OF_DAY, MINUTE, SECOND, and MILLISECOND.
0459      * We reserve only 4 interval patterns for a skeleton.
0460      *
0461      * @param field    calendar field
0462      * @param status   output param set to success/failure code on exit
0463      * @return  interval pattern index in hash table
0464      */
0465     static IntervalPatternIndex U_EXPORT2 calendarFieldToIntervalIndex(
0466                                                       UCalendarDateFields field,
0467                                                       UErrorCode& status);
0468 
0469 
0470     /**
0471      * delete hash table (of type fIntervalPatterns).
0472      *
0473      * @param hTable  hash table to be deleted
0474      */
0475     void deleteHash(Hashtable* hTable);
0476 
0477 
0478     /**
0479      * initialize hash table (of type fIntervalPatterns).
0480      *
0481      * @param status   output param set to success/failure code on exit
0482      * @return         hash table initialized
0483      */
0484     Hashtable* initHash(UErrorCode& status);
0485 
0486 
0487 
0488     /**
0489      * copy hash table (of type fIntervalPatterns).
0490      *
0491      * @param source   the source to copy from
0492      * @param target   the target to copy to
0493      * @param status   output param set to success/failure code on exit
0494      */
0495     void copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status);
0496 
0497 
0498     // data members
0499     // fallback interval pattern
0500     UnicodeString fFallbackIntervalPattern;
0501     // default order
0502     UBool fFirstDateInPtnIsLaterDate;
0503 
0504     // HashMap<UnicodeString, UnicodeString[kIPI_MAX_INDEX]>
0505     // HashMap( skeleton, pattern[largest_different_field] )
0506     Hashtable* fIntervalPatterns;
0507 
0508 };// end class DateIntervalInfo
0509 
0510 
0511 inline bool
0512 DateIntervalInfo::operator!=(const DateIntervalInfo& other) const {
0513     return !operator==(other);
0514 }
0515 
0516 
0517 U_NAMESPACE_END
0518 
0519 #endif
0520 
0521 #endif /* U_SHOW_CPLUSPLUS_API */
0522 
0523 #endif
0524