• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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