2 *****************************************************************************
3 * Copyright (C) 2014-2016, International Business Machines Corporation and
6 *****************************************************************************
9 *****************************************************************************
12 #ifndef __RELDATEFMT_H
13 #define __RELDATEFMT_H
15 #include "unicode/utypes.h"
16 #include "unicode/uobject.h"
17 #include "unicode/udisplaycontext.h"
18 #include "unicode/ureldatefmt.h"
19 #include "unicode/locid.h"
23 * \brief C++ API: Formats relative dates such as "1 day ago" or "tomorrow"
26 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
29 * Represents the unit for formatting a relative date. e.g "in 5 days"
33 typedef enum UDateRelativeUnit
{
39 UDAT_RELATIVE_SECONDS
,
45 UDAT_RELATIVE_MINUTES
,
78 * Count of items in this enum.
81 UDAT_RELATIVE_UNIT_COUNT
85 * Represents an absolute unit.
88 typedef enum UDateAbsoluteUnit
{
90 // Days of week have to remain together and in order from Sunday to
102 UDAT_ABSOLUTE_MONDAY
,
108 UDAT_ABSOLUTE_TUESDAY
,
114 UDAT_ABSOLUTE_WEDNESDAY
,
120 UDAT_ABSOLUTE_THURSDAY
,
126 UDAT_ABSOLUTE_FRIDAY
,
132 UDAT_ABSOLUTE_SATURDAY
,
165 * Count of items in this enum.
168 UDAT_ABSOLUTE_UNIT_COUNT
172 * Represents a direction for an absolute unit e.g "Next Tuesday"
176 typedef enum UDateDirection
{
179 * Two before. Not fully supported in every locale.
182 UDAT_DIRECTION_LAST_2
,
203 * Two after. Not fully supported in every locale.
206 UDAT_DIRECTION_NEXT_2
,
209 * Plain, which means the absence of a qualifier.
212 UDAT_DIRECTION_PLAIN
,
215 * Count of items in this enum.
224 class RelativeDateTimeCacheData
;
225 class SharedNumberFormat
;
226 class SharedPluralRules
;
227 class SharedBreakIterator
;
232 * Formats simple relative dates. There are two types of relative dates that
235 * <li>relative dates with a quantity e.g "in 5 days"</li>
236 * <li>relative dates without a quantity e.g "next Tuesday"</li>
239 * This API is very basic and is intended to be a building block for more
240 * fancy APIs. The caller tells it exactly what to display in a locale
241 * independent way. While this class automatically provides the correct plural
242 * forms, the grammatical form is otherwise as neutral as possible. It is the
243 * caller's responsibility to handle cut-off logic such as deciding between
244 * displaying "in 7 days" or "in 1 week." This API supports relative dates
245 * involving one single unit. This API does not support relative dates
246 * involving compound units,
247 * e.g "in 5 days and 4 hours" nor does it support parsing.
249 * This class is mostly thread safe and immutable with the following caveats:
250 * 1. The assignment operator violates Immutability. It must not be used
251 * concurrently with other operations.
252 * 2. Caller must not hold onto adopted pointers.
254 * This class is not intended for public subclassing.
256 * Here are some examples of use:
259 * UErrorCode status = U_ZERO_ERROR;
260 * UnicodeString appendTo;
261 * RelativeDateTimeFormatter fmt(status);
262 * // Appends "in 1 day"
264 * 1, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status);
265 * // Appends "in 3 days"
267 * 3, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status);
268 * // Appends "3.2 years ago"
270 * 3.2, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, appendTo, status);
271 * // Appends "last Sunday"
272 * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
273 * // Appends "this Sunday"
274 * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
275 * // Appends "next Sunday"
276 * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
277 * // Appends "Sunday"
278 * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, appendTo, status);
280 * // Appends "yesterday"
281 * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, appendTo, status);
283 * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, appendTo, status);
284 * // Appends "tomorrow"
285 * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, appendTo, status);
287 * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, appendTo, status);
292 * In the future, we may add more forms, such as abbreviated/short forms
293 * (3 secs ago), and relative day periods ("yesterday afternoon"), etc.
295 * The RelativeDateTimeFormatter class is not intended for public subclassing.
299 class U_I18N_API RelativeDateTimeFormatter
: public UObject
{
303 * Create RelativeDateTimeFormatter with default locale.
306 RelativeDateTimeFormatter(UErrorCode
& status
);
309 * Create RelativeDateTimeFormatter with given locale.
312 RelativeDateTimeFormatter(const Locale
& locale
, UErrorCode
& status
);
315 * Create RelativeDateTimeFormatter with given locale and NumberFormat.
317 * @param locale the locale
318 * @param nfToAdopt Constructed object takes ownership of this pointer.
319 * It is an error for caller to delete this pointer or change its
320 * contents after calling this constructor.
321 * @status Any error is returned here.
324 RelativeDateTimeFormatter(
325 const Locale
& locale
, NumberFormat
*nfToAdopt
, UErrorCode
& status
);
328 * Create RelativeDateTimeFormatter with given locale, NumberFormat,
329 * and capitalization context.
331 * @param locale the locale
332 * @param nfToAdopt Constructed object takes ownership of this pointer.
333 * It is an error for caller to delete this pointer or change its
334 * contents after calling this constructor. Caller may pass NULL for
335 * this argument if they want default number format behavior.
336 * @param style the format style. The UDAT_RELATIVE bit field has no effect.
337 * @param capitalizationContext A value from UDisplayContext that pertains to
339 * @status Any error is returned here.
342 RelativeDateTimeFormatter(
343 const Locale
& locale
,
344 NumberFormat
*nfToAdopt
,
345 UDateRelativeDateTimeFormatterStyle style
,
346 UDisplayContext capitalizationContext
,
353 RelativeDateTimeFormatter(const RelativeDateTimeFormatter
& other
);
356 * Assignment operator.
359 RelativeDateTimeFormatter
& operator=(
360 const RelativeDateTimeFormatter
& other
);
366 virtual ~RelativeDateTimeFormatter();
369 * Formats a relative date with a quantity such as "in 5 days" or
371 * @param quantity The numerical amount e.g 5. This value is formatted
372 * according to this object's NumberFormat object.
373 * @param direction NEXT means a future relative date; LAST means a past
374 * relative date. If direction is anything else, this method sets
375 * status to U_ILLEGAL_ARGUMENT_ERROR.
376 * @param unit the unit e.g day? month? year?
377 * @param appendTo The string to which the formatted result will be
379 * @param status ICU error code returned here.
383 UnicodeString
& format(
385 UDateDirection direction
,
386 UDateRelativeUnit unit
,
387 UnicodeString
& appendTo
,
388 UErrorCode
& status
) const;
391 * Formats a relative date without a quantity.
392 * @param direction NEXT, LAST, THIS, etc.
393 * @param unit e.g SATURDAY, DAY, MONTH
394 * @param appendTo The string to which the formatted result will be
395 * appended. If the value of direction is documented as not being fully
396 * supported in all locales then this method leaves appendTo unchanged if
397 * no format string is available.
398 * @param status ICU error code returned here.
402 UnicodeString
& format(
403 UDateDirection direction
,
404 UDateAbsoluteUnit unit
,
405 UnicodeString
& appendTo
,
406 UErrorCode
& status
) const;
408 #ifndef U_HIDE_DRAFT_API
410 * Format a combination of URelativeDateTimeUnit and numeric offset
411 * using a numeric style, e.g. "1 week ago", "in 1 week",
412 * "5 weeks ago", "in 5 weeks".
414 * @param offset The signed offset for the specified unit. This
415 * will be formatted according to this object's
416 * NumberFormat object.
417 * @param unit The unit to use when formatting the relative
418 * date, e.g. UDAT_REL_UNIT_WEEK,
419 * UDAT_REL_UNIT_FRIDAY.
420 * @param appendTo The string to which the formatted result will be
422 * @param status ICU error code returned here.
426 UnicodeString
& formatNumeric(
428 URelativeDateTimeUnit unit
,
429 UnicodeString
& appendTo
,
430 UErrorCode
& status
) const;
433 * Format a combination of URelativeDateTimeUnit and numeric offset
434 * using a text style if possible, e.g. "last week", "this week",
435 * "next week", "yesterday", "tomorrow". Falls back to numeric
436 * style if no appropriate text term is available for the specified
437 * offset in the object's locale.
439 * @param offset The signed offset for the specified unit.
440 * @param unit The unit to use when formatting the relative
441 * date, e.g. UDAT_REL_UNIT_WEEK,
442 * UDAT_REL_UNIT_FRIDAY.
443 * @param appendTo The string to which the formatted result will be
445 * @param status ICU error code returned here.
449 UnicodeString
& format(
451 URelativeDateTimeUnit unit
,
452 UnicodeString
& appendTo
,
453 UErrorCode
& status
) const;
454 #endif /* U_HIDE_DRAFT_API */
457 * Combines a relative date string and a time string in this object's
458 * locale. This is done with the same date-time separator used for the
459 * default calendar in this locale.
461 * @param relativeDateString the relative date, e.g 'yesterday'
462 * @param timeString the time e.g '3:45'
463 * @param appendTo concatenated date and time appended here
464 * @param status ICU error code returned here.
468 UnicodeString
& combineDateAndTime(
469 const UnicodeString
& relativeDateString
,
470 const UnicodeString
& timeString
,
471 UnicodeString
& appendTo
,
472 UErrorCode
& status
) const;
475 * Returns the NumberFormat this object is using.
479 const NumberFormat
& getNumberFormat() const;
482 * Returns the capitalization context.
486 UDisplayContext
getCapitalizationContext() const;
489 * Returns the format style.
493 UDateRelativeDateTimeFormatterStyle
getFormatStyle() const;
496 const RelativeDateTimeCacheData
* fCache
;
497 const SharedNumberFormat
*fNumberFormat
;
498 const SharedPluralRules
*fPluralRules
;
499 UDateRelativeDateTimeFormatterStyle fStyle
;
500 UDisplayContext fContext
;
501 const SharedBreakIterator
*fOptBreakIterator
;
504 NumberFormat
*nfToAdopt
,
505 BreakIterator
*brkIter
,
507 void adjustForContext(UnicodeString
&) const;
512 #endif /* !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION*/