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