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_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 BreakIterator; 234 class RelativeDateTimeCacheData; 235 class SharedNumberFormat; 236 class SharedPluralRules; 237 class SharedBreakIterator; 238 class NumberFormat; 239 class UnicodeString; 240 241 /** 242 * Formats simple relative dates. There are two types of relative dates that 243 * it handles: 244 * <ul> 245 * <li>relative dates with a quantity e.g "in 5 days"</li> 246 * <li>relative dates without a quantity e.g "next Tuesday"</li> 247 * </ul> 248 * <p> 249 * This API is very basic and is intended to be a building block for more 250 * fancy APIs. The caller tells it exactly what to display in a locale 251 * independent way. While this class automatically provides the correct plural 252 * forms, the grammatical form is otherwise as neutral as possible. It is the 253 * caller's responsibility to handle cut-off logic such as deciding between 254 * displaying "in 7 days" or "in 1 week." This API supports relative dates 255 * involving one single unit. This API does not support relative dates 256 * involving compound units, 257 * e.g "in 5 days and 4 hours" nor does it support parsing. 258 * <p> 259 * This class is mostly thread safe and immutable with the following caveats: 260 * 1. The assignment operator violates Immutability. It must not be used 261 * concurrently with other operations. 262 * 2. Caller must not hold onto adopted pointers. 263 * <p> 264 * This class is not intended for public subclassing. 265 * <p> 266 * Here are some examples of use: 267 * <blockquote> 268 * <pre> 269 * UErrorCode status = U_ZERO_ERROR; 270 * UnicodeString appendTo; 271 * RelativeDateTimeFormatter fmt(status); 272 * // Appends "in 1 day" 273 * fmt.format( 274 * 1, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status); 275 * // Appends "in 3 days" 276 * fmt.format( 277 * 3, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status); 278 * // Appends "3.2 years ago" 279 * fmt.format( 280 * 3.2, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, appendTo, status); 281 * // Appends "last Sunday" 282 * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 283 * // Appends "this Sunday" 284 * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 285 * // Appends "next Sunday" 286 * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 287 * // Appends "Sunday" 288 * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 289 * 290 * // Appends "yesterday" 291 * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, appendTo, status); 292 * // Appends "today" 293 * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, appendTo, status); 294 * // Appends "tomorrow" 295 * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, appendTo, status); 296 * // Appends "now" 297 * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, appendTo, status); 298 * 299 * </pre> 300 * </blockquote> 301 * <p> 302 * In the future, we may add more forms, such as abbreviated/short forms 303 * (3 secs ago), and relative day periods ("yesterday afternoon"), etc. 304 * 305 * The RelativeDateTimeFormatter class is not intended for public subclassing. 306 * 307 * @stable ICU 53 308 */ 309 class U_I18N_API RelativeDateTimeFormatter : public UObject { 310 public: 311 312 /** 313 * Create RelativeDateTimeFormatter with default locale. 314 * @stable ICU 53 315 */ 316 RelativeDateTimeFormatter(UErrorCode& status); 317 318 /** 319 * Create RelativeDateTimeFormatter with given locale. 320 * @stable ICU 53 321 */ 322 RelativeDateTimeFormatter(const Locale& locale, UErrorCode& status); 323 324 /** 325 * Create RelativeDateTimeFormatter with given locale and NumberFormat. 326 * 327 * @param locale the locale 328 * @param nfToAdopt Constructed object takes ownership of this pointer. 329 * It is an error for caller to delete this pointer or change its 330 * contents after calling this constructor. 331 * @status Any error is returned here. 332 * @stable ICU 53 333 */ 334 RelativeDateTimeFormatter( 335 const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status); 336 337 /** 338 * Create RelativeDateTimeFormatter with given locale, NumberFormat, 339 * and capitalization context. 340 * 341 * @param locale the locale 342 * @param nfToAdopt Constructed object takes ownership of this pointer. 343 * It is an error for caller to delete this pointer or change its 344 * contents after calling this constructor. Caller may pass NULL for 345 * this argument if they want default number format behavior. 346 * @param style the format style. The UDAT_RELATIVE bit field has no effect. 347 * @param capitalizationContext A value from UDisplayContext that pertains to 348 * capitalization. 349 * @status Any error is returned here. 350 * @stable ICU 54 351 */ 352 RelativeDateTimeFormatter( 353 const Locale& locale, 354 NumberFormat *nfToAdopt, 355 UDateRelativeDateTimeFormatterStyle style, 356 UDisplayContext capitalizationContext, 357 UErrorCode& status); 358 359 /** 360 * Copy constructor. 361 * @stable ICU 53 362 */ 363 RelativeDateTimeFormatter(const RelativeDateTimeFormatter& other); 364 365 /** 366 * Assignment operator. 367 * @stable ICU 53 368 */ 369 RelativeDateTimeFormatter& operator=( 370 const RelativeDateTimeFormatter& other); 371 372 /** 373 * Destructor. 374 * @stable ICU 53 375 */ 376 virtual ~RelativeDateTimeFormatter(); 377 378 /** 379 * Formats a relative date with a quantity such as "in 5 days" or 380 * "3 months ago" 381 * @param quantity The numerical amount e.g 5. This value is formatted 382 * according to this object's NumberFormat object. 383 * @param direction NEXT means a future relative date; LAST means a past 384 * relative date. If direction is anything else, this method sets 385 * status to U_ILLEGAL_ARGUMENT_ERROR. 386 * @param unit the unit e.g day? month? year? 387 * @param appendTo The string to which the formatted result will be 388 * appended 389 * @param status ICU error code returned here. 390 * @return appendTo 391 * @stable ICU 53 392 */ 393 UnicodeString& format( 394 double quantity, 395 UDateDirection direction, 396 UDateRelativeUnit unit, 397 UnicodeString& appendTo, 398 UErrorCode& status) const; 399 400 /** 401 * Formats a relative date without a quantity. 402 * @param direction NEXT, LAST, THIS, etc. 403 * @param unit e.g SATURDAY, DAY, MONTH 404 * @param appendTo The string to which the formatted result will be 405 * appended. If the value of direction is documented as not being fully 406 * supported in all locales then this method leaves appendTo unchanged if 407 * no format string is available. 408 * @param status ICU error code returned here. 409 * @return appendTo 410 * @stable ICU 53 411 */ 412 UnicodeString& format( 413 UDateDirection direction, 414 UDateAbsoluteUnit unit, 415 UnicodeString& appendTo, 416 UErrorCode& status) const; 417 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 * @stable 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 * @stable ICU 57 457 */ 458 UnicodeString& format( 459 double offset, 460 URelativeDateTimeUnit unit, 461 UnicodeString& appendTo, 462 UErrorCode& status) const; 463 464 /** 465 * Combines a relative date string and a time string in this object's 466 * locale. This is done with the same date-time separator used for the 467 * default calendar in this locale. 468 * 469 * @param relativeDateString the relative date, e.g 'yesterday' 470 * @param timeString the time e.g '3:45' 471 * @param appendTo concatenated date and time appended here 472 * @param status ICU error code returned here. 473 * @return appendTo 474 * @stable ICU 53 475 */ 476 UnicodeString& combineDateAndTime( 477 const UnicodeString& relativeDateString, 478 const UnicodeString& timeString, 479 UnicodeString& appendTo, 480 UErrorCode& status) const; 481 482 /** 483 * Returns the NumberFormat this object is using. 484 * 485 * @stable ICU 53 486 */ 487 const NumberFormat& getNumberFormat() const; 488 489 /** 490 * Returns the capitalization context. 491 * 492 * @stable ICU 54 493 */ 494 UDisplayContext getCapitalizationContext() const; 495 496 /** 497 * Returns the format style. 498 * 499 * @stable ICU 54 500 */ 501 UDateRelativeDateTimeFormatterStyle getFormatStyle() const; 502 503 private: 504 const RelativeDateTimeCacheData* fCache; 505 const SharedNumberFormat *fNumberFormat; 506 const SharedPluralRules *fPluralRules; 507 UDateRelativeDateTimeFormatterStyle fStyle; 508 UDisplayContext fContext; 509 const SharedBreakIterator *fOptBreakIterator; 510 Locale fLocale; 511 void init( 512 NumberFormat *nfToAdopt, 513 BreakIterator *brkIter, 514 UErrorCode &status); 515 void adjustForContext(UnicodeString &) const; 516 }; 517 518 U_NAMESPACE_END 519 520 #endif /* !UCONFIG_NO_BREAK_ITERATION */ 521 #endif /* !UCONFIG_NO_FORMATTING */ 522 #endif /* __RELDATEFMT_H */ 523