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