• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 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_DEPRECATED_API
169     /**
170      * One more than the highest normal UDateAbsoluteUnit value.
171      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
172      */
173     UDAT_ABSOLUTE_UNIT_COUNT
174 #endif  // U_HIDE_DEPRECATED_API
175 } UDateAbsoluteUnit;
176 
177 /**
178  * Represents a direction for an absolute unit e.g "Next Tuesday"
179  * or "Last Tuesday"
180  * @stable ICU 53
181  */
182 typedef enum UDateDirection {
183 
184     /**
185      * Two before. Not fully supported in every locale.
186      * @stable ICU 53
187      */
188     UDAT_DIRECTION_LAST_2,
189 
190     /**
191      * Last
192      * @stable ICU 53
193      */
194     UDAT_DIRECTION_LAST,
195 
196     /**
197      * This
198      * @stable ICU 53
199      */
200     UDAT_DIRECTION_THIS,
201 
202     /**
203      * Next
204      * @stable ICU 53
205      */
206     UDAT_DIRECTION_NEXT,
207 
208     /**
209      * Two after. Not fully supported in every locale.
210      * @stable ICU 53
211      */
212     UDAT_DIRECTION_NEXT_2,
213 
214     /**
215      * Plain, which means the absence of a qualifier.
216      * @stable ICU 53
217      */
218     UDAT_DIRECTION_PLAIN,
219 
220 #ifndef U_HIDE_DEPRECATED_API
221     /**
222      * One more than the highest normal UDateDirection value.
223      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
224      */
225     UDAT_DIRECTION_COUNT
226 #endif  // U_HIDE_DEPRECATED_API
227 } UDateDirection;
228 
229 #if !UCONFIG_NO_BREAK_ITERATION
230 
231 U_NAMESPACE_BEGIN
232 
233 class RelativeDateTimeCacheData;
234 class SharedNumberFormat;
235 class SharedPluralRules;
236 class SharedBreakIterator;
237 class NumberFormat;
238 class UnicodeString;
239 
240 /**
241  * Formats simple relative dates. There are two types of relative dates that
242  * it handles:
243  * <ul>
244  *   <li>relative dates with a quantity e.g "in 5 days"</li>
245  *   <li>relative dates without a quantity e.g "next Tuesday"</li>
246  * </ul>
247  * <p>
248  * This API is very basic and is intended to be a building block for more
249  * fancy APIs. The caller tells it exactly what to display in a locale
250  * independent way. While this class automatically provides the correct plural
251  * forms, the grammatical form is otherwise as neutral as possible. It is the
252  * caller's responsibility to handle cut-off logic such as deciding between
253  * displaying "in 7 days" or "in 1 week." This API supports relative dates
254  * involving one single unit. This API does not support relative dates
255  * involving compound units,
256  * e.g "in 5 days and 4 hours" nor does it support parsing.
257  * <p>
258  * This class is mostly thread safe and immutable with the following caveats:
259  * 1. The assignment operator violates Immutability. It must not be used
260  *    concurrently with other operations.
261  * 2. Caller must not hold onto adopted pointers.
262  * <p>
263  * This class is not intended for public subclassing.
264  * <p>
265  * Here are some examples of use:
266  * <blockquote>
267  * <pre>
268  * UErrorCode status = U_ZERO_ERROR;
269  * UnicodeString appendTo;
270  * RelativeDateTimeFormatter fmt(status);
271  * // Appends "in 1 day"
272  * fmt.format(
273  *     1, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status);
274  * // Appends "in 3 days"
275  * fmt.format(
276  *     3, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status);
277  * // Appends "3.2 years ago"
278  * fmt.format(
279  *     3.2, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, appendTo, status);
280  * // Appends "last Sunday"
281  * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
282  * // Appends "this Sunday"
283  * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
284  * // Appends "next Sunday"
285  * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
286  * // Appends "Sunday"
287  * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
288  *
289  * // Appends "yesterday"
290  * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, appendTo, status);
291  * // Appends "today"
292  * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, appendTo, status);
293  * // Appends "tomorrow"
294  * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, appendTo, status);
295  * // Appends "now"
296  * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, appendTo, status);
297  *
298  * </pre>
299  * </blockquote>
300  * <p>
301  * In the future, we may add more forms, such as abbreviated/short forms
302  * (3 secs ago), and relative day periods ("yesterday afternoon"), etc.
303  *
304  * The RelativeDateTimeFormatter class is not intended for public subclassing.
305  *
306  * @stable ICU 53
307  */
308 class U_I18N_API RelativeDateTimeFormatter : public UObject {
309 public:
310 
311     /**
312      * Create RelativeDateTimeFormatter with default locale.
313      * @stable ICU 53
314      */
315     RelativeDateTimeFormatter(UErrorCode& status);
316 
317     /**
318      * Create RelativeDateTimeFormatter with given locale.
319      * @stable ICU 53
320      */
321     RelativeDateTimeFormatter(const Locale& locale, UErrorCode& status);
322 
323     /**
324      * Create RelativeDateTimeFormatter with given locale and NumberFormat.
325      *
326      * @param locale the locale
327      * @param nfToAdopt Constructed object takes ownership of this pointer.
328      *   It is an error for caller to delete this pointer or change its
329      *   contents after calling this constructor.
330      * @status Any error is returned here.
331      * @stable ICU 53
332      */
333     RelativeDateTimeFormatter(
334         const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status);
335 
336     /**
337      * Create RelativeDateTimeFormatter with given locale, NumberFormat,
338      * and capitalization context.
339      *
340      * @param locale the locale
341      * @param nfToAdopt Constructed object takes ownership of this pointer.
342      *   It is an error for caller to delete this pointer or change its
343      *   contents after calling this constructor. Caller may pass NULL for
344      *   this argument if they want default number format behavior.
345      * @param style the format style. The UDAT_RELATIVE bit field has no effect.
346      * @param capitalizationContext A value from UDisplayContext that pertains to
347      * capitalization.
348      * @status Any error is returned here.
349      * @stable ICU 54
350      */
351     RelativeDateTimeFormatter(
352             const Locale& locale,
353             NumberFormat *nfToAdopt,
354             UDateRelativeDateTimeFormatterStyle style,
355             UDisplayContext capitalizationContext,
356             UErrorCode& status);
357 
358     /**
359      * Copy constructor.
360      * @stable ICU 53
361      */
362     RelativeDateTimeFormatter(const RelativeDateTimeFormatter& other);
363 
364     /**
365      * Assignment operator.
366      * @stable ICU 53
367      */
368     RelativeDateTimeFormatter& operator=(
369             const RelativeDateTimeFormatter& other);
370 
371     /**
372      * Destructor.
373      * @stable ICU 53
374      */
375     virtual ~RelativeDateTimeFormatter();
376 
377     /**
378      * Formats a relative date with a quantity such as "in 5 days" or
379      * "3 months ago"
380      * @param quantity The numerical amount e.g 5. This value is formatted
381      * according to this object's NumberFormat object.
382      * @param direction NEXT means a future relative date; LAST means a past
383      * relative date. If direction is anything else, this method sets
384      * status to U_ILLEGAL_ARGUMENT_ERROR.
385      * @param unit the unit e.g day? month? year?
386      * @param appendTo The string to which the formatted result will be
387      *  appended
388      * @param status ICU error code returned here.
389      * @return appendTo
390      * @stable ICU 53
391      */
392     UnicodeString& format(
393             double quantity,
394             UDateDirection direction,
395             UDateRelativeUnit unit,
396             UnicodeString& appendTo,
397             UErrorCode& status) const;
398 
399     /**
400      * Formats a relative date without a quantity.
401      * @param direction NEXT, LAST, THIS, etc.
402      * @param unit e.g SATURDAY, DAY, MONTH
403      * @param appendTo The string to which the formatted result will be
404      *  appended. If the value of direction is documented as not being fully
405      *  supported in all locales then this method leaves appendTo unchanged if
406      *  no format string is available.
407      * @param status ICU error code returned here.
408      * @return appendTo
409      * @stable ICU 53
410      */
411     UnicodeString& format(
412             UDateDirection direction,
413             UDateAbsoluteUnit unit,
414             UnicodeString& appendTo,
415             UErrorCode& status) const;
416 
417 #ifndef U_HIDE_DRAFT_API
418     /**
419      * Format a combination of URelativeDateTimeUnit and numeric offset
420      * using a numeric style, e.g. "1 week ago", "in 1 week",
421      * "5 weeks ago", "in 5 weeks".
422      *
423      * @param offset    The signed offset for the specified unit. This
424      *                  will be formatted according to this object's
425      *                  NumberFormat object.
426      * @param unit      The unit to use when formatting the relative
427      *                  date, e.g. UDAT_REL_UNIT_WEEK,
428      *                  UDAT_REL_UNIT_FRIDAY.
429      * @param appendTo  The string to which the formatted result will be
430      *                  appended.
431      * @param status    ICU error code returned here.
432      * @return          appendTo
433      * @draft ICU 57
434      */
435     UnicodeString& formatNumeric(
436             double offset,
437             URelativeDateTimeUnit unit,
438             UnicodeString& appendTo,
439             UErrorCode& status) const;
440 
441     /**
442      * Format a combination of URelativeDateTimeUnit and numeric offset
443      * using a text style if possible, e.g. "last week", "this week",
444      * "next week", "yesterday", "tomorrow". Falls back to numeric
445      * style if no appropriate text term is available for the specified
446      * offset in the object's locale.
447      *
448      * @param offset    The signed offset for the specified unit.
449      * @param unit      The unit to use when formatting the relative
450      *                  date, e.g. UDAT_REL_UNIT_WEEK,
451      *                  UDAT_REL_UNIT_FRIDAY.
452      * @param appendTo  The string to which the formatted result will be
453      *                  appended.
454      * @param status    ICU error code returned here.
455      * @return          appendTo
456      * @draft ICU 57
457      */
458     UnicodeString& format(
459             double offset,
460             URelativeDateTimeUnit unit,
461             UnicodeString& appendTo,
462             UErrorCode& status) const;
463 #endif  /* U_HIDE_DRAFT_API */
464 
465     /**
466      * Combines a relative date string and a time string in this object's
467      * locale. This is done with the same date-time separator used for the
468      * default calendar in this locale.
469      *
470      * @param relativeDateString the relative date, e.g 'yesterday'
471      * @param timeString the time e.g '3:45'
472      * @param appendTo concatenated date and time appended here
473      * @param status ICU error code returned here.
474      * @return appendTo
475      * @stable ICU 53
476      */
477     UnicodeString& combineDateAndTime(
478             const UnicodeString& relativeDateString,
479             const UnicodeString& timeString,
480             UnicodeString& appendTo,
481             UErrorCode& status) const;
482 
483     /**
484      * Returns the NumberFormat this object is using.
485      *
486      * @stable ICU 53
487      */
488     const NumberFormat& getNumberFormat() const;
489 
490     /**
491      * Returns the capitalization context.
492      *
493      * @stable ICU 54
494      */
495     UDisplayContext getCapitalizationContext() const;
496 
497     /**
498      * Returns the format style.
499      *
500      * @stable ICU 54
501      */
502     UDateRelativeDateTimeFormatterStyle getFormatStyle() const;
503 
504 private:
505     const RelativeDateTimeCacheData* fCache;
506     const SharedNumberFormat *fNumberFormat;
507     const SharedPluralRules *fPluralRules;
508     UDateRelativeDateTimeFormatterStyle fStyle;
509     UDisplayContext fContext;
510     const SharedBreakIterator *fOptBreakIterator;
511     Locale fLocale;
512     void init(
513             NumberFormat *nfToAdopt,
514             BreakIterator *brkIter,
515             UErrorCode &status);
516     void adjustForContext(UnicodeString &) const;
517 };
518 
519 U_NAMESPACE_END
520 
521 #endif /* !UCONFIG_NO_BREAK_ITERATION */
522 #endif /* !UCONFIG_NO_FORMATTING */
523 #endif /* __RELDATEFMT_H */
524