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