Home | History | Annotate | Download | only in unicode
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 *****************************************************************************
      5 * Copyright (C) 2014-2016, International Business Machines Corporation and
      6 * others.
      7 * All Rights Reserved.
      8 *****************************************************************************
      9 *
     10 * File RELDATEFMT.H
     11 *****************************************************************************
     12 */
     13 
     14 #ifndef __RELDATEFMT_H
     15 #define __RELDATEFMT_H
     16 
     17 #include "unicode/utypes.h"
     18 #include "unicode/uobject.h"
     19 #include "unicode/udisplaycontext.h"
     20 #include "unicode/ureldatefmt.h"
     21 #include "unicode/locid.h"
     22 
     23 /**
     24  * \file
     25  * \brief C++ API: Formats relative dates such as "1 day ago" or "tomorrow"
     26  */
     27 
     28 #if !UCONFIG_NO_FORMATTING
     29 
     30 /**
     31  * Represents the unit for formatting a relative date. e.g "in 5 days"
     32  * or "in 3 months"
     33  * @stable ICU 53
     34  */
     35 typedef enum UDateRelativeUnit {
     36 
     37     /**
     38      * Seconds
     39      * @stable ICU 53
     40      */
     41     UDAT_RELATIVE_SECONDS,
     42 
     43     /**
     44      * Minutes
     45      * @stable ICU 53
     46      */
     47     UDAT_RELATIVE_MINUTES,
     48 
     49     /**
     50      * Hours
     51      * @stable ICU 53
     52      */
     53     UDAT_RELATIVE_HOURS,
     54 
     55     /**
     56      * Days
     57      * @stable ICU 53
     58      */
     59     UDAT_RELATIVE_DAYS,
     60 
     61     /**
     62      * Weeks
     63      * @stable ICU 53
     64      */
     65     UDAT_RELATIVE_WEEKS,
     66 
     67     /**
     68      * Months
     69      * @stable ICU 53
     70      */
     71     UDAT_RELATIVE_MONTHS,
     72 
     73     /**
     74      * Years
     75      * @stable ICU 53
     76      */
     77     UDAT_RELATIVE_YEARS,
     78 
     79 #ifndef U_HIDE_DEPRECATED_API
     80     /**
     81      * One more than the highest normal UDateRelativeUnit value.
     82      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
     83      */
     84     UDAT_RELATIVE_UNIT_COUNT
     85 #endif  // U_HIDE_DEPRECATED_API
     86 } UDateRelativeUnit;
     87 
     88 /**
     89  * Represents an absolute unit.
     90  * @stable ICU 53
     91  */
     92 typedef enum UDateAbsoluteUnit {
     93 
     94     // Days of week have to remain together and in order from Sunday to
     95     // Saturday.
     96     /**
     97      * Sunday
     98      * @stable ICU 53
     99      */
    100     UDAT_ABSOLUTE_SUNDAY,
    101 
    102     /**
    103      * Monday
    104      * @stable ICU 53
    105      */
    106     UDAT_ABSOLUTE_MONDAY,
    107 
    108     /**
    109      * Tuesday
    110      * @stable ICU 53
    111      */
    112     UDAT_ABSOLUTE_TUESDAY,
    113 
    114     /**
    115      * Wednesday
    116      * @stable ICU 53
    117      */
    118     UDAT_ABSOLUTE_WEDNESDAY,
    119 
    120     /**
    121      * Thursday
    122      * @stable ICU 53
    123      */
    124     UDAT_ABSOLUTE_THURSDAY,
    125 
    126     /**
    127      * Friday
    128      * @stable ICU 53
    129      */
    130     UDAT_ABSOLUTE_FRIDAY,
    131 
    132     /**
    133      * Saturday
    134      * @stable ICU 53
    135      */
    136     UDAT_ABSOLUTE_SATURDAY,
    137 
    138     /**
    139      * Day
    140      * @stable ICU 53
    141      */
    142     UDAT_ABSOLUTE_DAY,
    143 
    144     /**
    145      * Week
    146      * @stable ICU 53
    147      */
    148     UDAT_ABSOLUTE_WEEK,
    149 
    150     /**
    151      * Month
    152      * @stable ICU 53
    153      */
    154     UDAT_ABSOLUTE_MONTH,
    155 
    156     /**
    157      * Year
    158      * @stable ICU 53
    159      */
    160     UDAT_ABSOLUTE_YEAR,
    161 
    162     /**
    163      * Now
    164      * @stable ICU 53
    165      */
    166     UDAT_ABSOLUTE_NOW,
    167 
    168 #ifndef U_HIDE_DRAFT_API
    169     /**
    170      * Quarter
    171      * @draft ICU 63
    172      */
    173     UDAT_ABSOLUTE_QUARTER,
    174 #endif // U_HIDE_DRAFT_API
    175 
    176 #ifndef U_HIDE_DEPRECATED_API
    177     /**
    178      * One more than the highest normal UDateAbsoluteUnit value.
    179      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
    180      */
    181     UDAT_ABSOLUTE_UNIT_COUNT = UDAT_ABSOLUTE_NOW + 2
    182 #endif  // U_HIDE_DEPRECATED_API
    183 } UDateAbsoluteUnit;
    184 
    185 /**
    186  * Represents a direction for an absolute unit e.g "Next Tuesday"
    187  * or "Last Tuesday"
    188  * @stable ICU 53
    189  */
    190 typedef enum UDateDirection {
    191 
    192     /**
    193      * Two before. Not fully supported in every locale.
    194      * @stable ICU 53
    195      */
    196     UDAT_DIRECTION_LAST_2,
    197 
    198     /**
    199      * Last
    200      * @stable ICU 53
    201      */
    202     UDAT_DIRECTION_LAST,
    203 
    204     /**
    205      * This
    206      * @stable ICU 53
    207      */
    208     UDAT_DIRECTION_THIS,
    209 
    210     /**
    211      * Next
    212      * @stable ICU 53
    213      */
    214     UDAT_DIRECTION_NEXT,
    215 
    216     /**
    217      * Two after. Not fully supported in every locale.
    218      * @stable ICU 53
    219      */
    220     UDAT_DIRECTION_NEXT_2,
    221 
    222     /**
    223      * Plain, which means the absence of a qualifier.
    224      * @stable ICU 53
    225      */
    226     UDAT_DIRECTION_PLAIN,
    227 
    228 #ifndef U_HIDE_DEPRECATED_API
    229     /**
    230      * One more than the highest normal UDateDirection value.
    231      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
    232      */
    233     UDAT_DIRECTION_COUNT
    234 #endif  // U_HIDE_DEPRECATED_API
    235 } UDateDirection;
    236 
    237 #if !UCONFIG_NO_BREAK_ITERATION
    238 
    239 U_NAMESPACE_BEGIN
    240 
    241 class BreakIterator;
    242 class RelativeDateTimeCacheData;
    243 class SharedNumberFormat;
    244 class SharedPluralRules;
    245 class SharedBreakIterator;
    246 class NumberFormat;
    247 class UnicodeString;
    248 
    249 /**
    250  * Formats simple relative dates. There are two types of relative dates that
    251  * it handles:
    252  * <ul>
    253  *   <li>relative dates with a quantity e.g "in 5 days"</li>
    254  *   <li>relative dates without a quantity e.g "next Tuesday"</li>
    255  * </ul>
    256  * <p>
    257  * This API is very basic and is intended to be a building block for more
    258  * fancy APIs. The caller tells it exactly what to display in a locale
    259  * independent way. While this class automatically provides the correct plural
    260  * forms, the grammatical form is otherwise as neutral as possible. It is the
    261  * caller's responsibility to handle cut-off logic such as deciding between
    262  * displaying "in 7 days" or "in 1 week." This API supports relative dates
    263  * involving one single unit. This API does not support relative dates
    264  * involving compound units,
    265  * e.g "in 5 days and 4 hours" nor does it support parsing.
    266  * <p>
    267  * This class is mostly thread safe and immutable with the following caveats:
    268  * 1. The assignment operator violates Immutability. It must not be used
    269  *    concurrently with other operations.
    270  * 2. Caller must not hold onto adopted pointers.
    271  * <p>
    272  * This class is not intended for public subclassing.
    273  * <p>
    274  * Here are some examples of use:
    275  * <blockquote>
    276  * <pre>
    277  * UErrorCode status = U_ZERO_ERROR;
    278  * UnicodeString appendTo;
    279  * RelativeDateTimeFormatter fmt(status);
    280  * // Appends "in 1 day"
    281  * fmt.format(
    282  *     1, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status);
    283  * // Appends "in 3 days"
    284  * fmt.format(
    285  *     3, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status);
    286  * // Appends "3.2 years ago"
    287  * fmt.format(
    288  *     3.2, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, appendTo, status);
    289  * // Appends "last Sunday"
    290  * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
    291  * // Appends "this Sunday"
    292  * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
    293  * // Appends "next Sunday"
    294  * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
    295  * // Appends "Sunday"
    296  * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
    297  *
    298  * // Appends "yesterday"
    299  * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, appendTo, status);
    300  * // Appends "today"
    301  * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, appendTo, status);
    302  * // Appends "tomorrow"
    303  * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, appendTo, status);
    304  * // Appends "now"
    305  * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, appendTo, status);
    306  *
    307  * </pre>
    308  * </blockquote>
    309  * <p>
    310  * In the future, we may add more forms, such as abbreviated/short forms
    311  * (3 secs ago), and relative day periods ("yesterday afternoon"), etc.
    312  *
    313  * The RelativeDateTimeFormatter class is not intended for public subclassing.
    314  *
    315  * @stable ICU 53
    316  */
    317 class U_I18N_API RelativeDateTimeFormatter : public UObject {
    318 public:
    319 
    320     /**
    321      * Create RelativeDateTimeFormatter with default locale.
    322      * @stable ICU 53
    323      */
    324     RelativeDateTimeFormatter(UErrorCode& status);
    325 
    326     /**
    327      * Create RelativeDateTimeFormatter with given locale.
    328      * @stable ICU 53
    329      */
    330     RelativeDateTimeFormatter(const Locale& locale, UErrorCode& status);
    331 
    332     /**
    333      * Create RelativeDateTimeFormatter with given locale and NumberFormat.
    334      *
    335      * @param locale the locale
    336      * @param nfToAdopt Constructed object takes ownership of this pointer.
    337      *   It is an error for caller to delete this pointer or change its
    338      *   contents after calling this constructor.
    339      * @param status Any error is returned here.
    340      * @stable ICU 53
    341      */
    342     RelativeDateTimeFormatter(
    343         const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status);
    344 
    345     /**
    346      * Create RelativeDateTimeFormatter with given locale, NumberFormat,
    347      * and capitalization context.
    348      *
    349      * @param locale the locale
    350      * @param nfToAdopt Constructed object takes ownership of this pointer.
    351      *   It is an error for caller to delete this pointer or change its
    352      *   contents after calling this constructor. Caller may pass NULL for
    353      *   this argument if they want default number format behavior.
    354      * @param style the format style. The UDAT_RELATIVE bit field has no effect.
    355      * @param capitalizationContext A value from UDisplayContext that pertains to
    356      * capitalization.
    357      * @param status Any error is returned here.
    358      * @stable ICU 54
    359      */
    360     RelativeDateTimeFormatter(
    361             const Locale& locale,
    362             NumberFormat *nfToAdopt,
    363             UDateRelativeDateTimeFormatterStyle style,
    364             UDisplayContext capitalizationContext,
    365             UErrorCode& status);
    366 
    367     /**
    368      * Copy constructor.
    369      * @stable ICU 53
    370      */
    371     RelativeDateTimeFormatter(const RelativeDateTimeFormatter& other);
    372 
    373     /**
    374      * Assignment operator.
    375      * @stable ICU 53
    376      */
    377     RelativeDateTimeFormatter& operator=(
    378             const RelativeDateTimeFormatter& other);
    379 
    380     /**
    381      * Destructor.
    382      * @stable ICU 53
    383      */
    384     virtual ~RelativeDateTimeFormatter();
    385 
    386     /**
    387      * Formats a relative date with a quantity such as "in 5 days" or
    388      * "3 months ago"
    389      * @param quantity The numerical amount e.g 5. This value is formatted
    390      * according to this object's NumberFormat object.
    391      * @param direction NEXT means a future relative date; LAST means a past
    392      * relative date. If direction is anything else, this method sets
    393      * status to U_ILLEGAL_ARGUMENT_ERROR.
    394      * @param unit the unit e.g day? month? year?
    395      * @param appendTo The string to which the formatted result will be
    396      *  appended
    397      * @param status ICU error code returned here.
    398      * @return appendTo
    399      * @stable ICU 53
    400      */
    401     UnicodeString& format(
    402             double quantity,
    403             UDateDirection direction,
    404             UDateRelativeUnit unit,
    405             UnicodeString& appendTo,
    406             UErrorCode& status) const;
    407 
    408     /**
    409      * Formats a relative date without a quantity.
    410      * @param direction NEXT, LAST, THIS, etc.
    411      * @param unit e.g SATURDAY, DAY, MONTH
    412      * @param appendTo The string to which the formatted result will be
    413      *  appended. If the value of direction is documented as not being fully
    414      *  supported in all locales then this method leaves appendTo unchanged if
    415      *  no format string is available.
    416      * @param status ICU error code returned here.
    417      * @return appendTo
    418      * @stable ICU 53
    419      */
    420     UnicodeString& format(
    421             UDateDirection direction,
    422             UDateAbsoluteUnit unit,
    423             UnicodeString& appendTo,
    424             UErrorCode& status) const;
    425 
    426     /**
    427      * Format a combination of URelativeDateTimeUnit and numeric offset
    428      * using a numeric style, e.g. "1 week ago", "in 1 week",
    429      * "5 weeks ago", "in 5 weeks".
    430      *
    431      * @param offset    The signed offset for the specified unit. This
    432      *                  will be formatted according to this object's
    433      *                  NumberFormat object.
    434      * @param unit      The unit to use when formatting the relative
    435      *                  date, e.g. UDAT_REL_UNIT_WEEK,
    436      *                  UDAT_REL_UNIT_FRIDAY.
    437      * @param appendTo  The string to which the formatted result will be
    438      *                  appended.
    439      * @param status    ICU error code returned here.
    440      * @return          appendTo
    441      * @stable ICU 57
    442      */
    443     UnicodeString& formatNumeric(
    444             double offset,
    445             URelativeDateTimeUnit unit,
    446             UnicodeString& appendTo,
    447             UErrorCode& status) const;
    448 
    449     /**
    450      * Format a combination of URelativeDateTimeUnit and numeric offset
    451      * using a text style if possible, e.g. "last week", "this week",
    452      * "next week", "yesterday", "tomorrow". Falls back to numeric
    453      * style if no appropriate text term is available for the specified
    454      * offset in the object's locale.
    455      *
    456      * @param offset    The signed offset for the specified unit.
    457      * @param unit      The unit to use when formatting the relative
    458      *                  date, e.g. UDAT_REL_UNIT_WEEK,
    459      *                  UDAT_REL_UNIT_FRIDAY.
    460      * @param appendTo  The string to which the formatted result will be
    461      *                  appended.
    462      * @param status    ICU error code returned here.
    463      * @return          appendTo
    464      * @stable ICU 57
    465      */
    466     UnicodeString& format(
    467             double offset,
    468             URelativeDateTimeUnit unit,
    469             UnicodeString& appendTo,
    470             UErrorCode& status) const;
    471 
    472     /**
    473      * Combines a relative date string and a time string in this object's
    474      * locale. This is done with the same date-time separator used for the
    475      * default calendar in this locale.
    476      *
    477      * @param relativeDateString the relative date, e.g 'yesterday'
    478      * @param timeString the time e.g '3:45'
    479      * @param appendTo concatenated date and time appended here
    480      * @param status ICU error code returned here.
    481      * @return appendTo
    482      * @stable ICU 53
    483      */
    484     UnicodeString& combineDateAndTime(
    485             const UnicodeString& relativeDateString,
    486             const UnicodeString& timeString,
    487             UnicodeString& appendTo,
    488             UErrorCode& status) const;
    489 
    490     /**
    491      * Returns the NumberFormat this object is using.
    492      *
    493      * @stable ICU 53
    494      */
    495     const NumberFormat& getNumberFormat() const;
    496 
    497     /**
    498      * Returns the capitalization context.
    499      *
    500      * @stable ICU 54
    501      */
    502     UDisplayContext getCapitalizationContext() const;
    503 
    504     /**
    505      * Returns the format style.
    506      *
    507      * @stable ICU 54
    508      */
    509     UDateRelativeDateTimeFormatterStyle getFormatStyle() const;
    510 
    511 private:
    512     const RelativeDateTimeCacheData* fCache;
    513     const SharedNumberFormat *fNumberFormat;
    514     const SharedPluralRules *fPluralRules;
    515     UDateRelativeDateTimeFormatterStyle fStyle;
    516     UDisplayContext fContext;
    517     const SharedBreakIterator *fOptBreakIterator;
    518     Locale fLocale;
    519     void init(
    520             NumberFormat *nfToAdopt,
    521             BreakIterator *brkIter,
    522             UErrorCode &status);
    523     void adjustForContext(UnicodeString &) const;
    524 };
    525 
    526 U_NAMESPACE_END
    527 
    528 #endif /* !UCONFIG_NO_BREAK_ITERATION */
    529 #endif /* !UCONFIG_NO_FORMATTING */
    530 #endif /* __RELDATEFMT_H */
    531