1 /* 2 ***************************************************************************** 3 * Copyright (C) 2014-2015, International Business Machines Corporation and 4 * others. 5 * All Rights Reserved. 6 ***************************************************************************** 7 * 8 * File RELDATEFMT.H 9 ***************************************************************************** 10 */ 11 12 #ifndef __RELDATEFMT_H 13 #define __RELDATEFMT_H 14 15 #include "unicode/utypes.h" 16 #include "unicode/uobject.h" 17 #include "unicode/udisplaycontext.h" 18 #include "unicode/locid.h" 19 20 /** 21 * \file 22 * \brief C++ API: Formats relative dates such as "1 day ago" or "tomorrow" 23 */ 24 25 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION 26 27 /** 28 * The formatting style 29 * @stable ICU 54 30 */ 31 typedef enum UDateRelativeDateTimeFormatterStyle { 32 /** 33 * Everything spelled out. 34 * @stable ICU 54 35 */ 36 UDAT_STYLE_LONG, 37 38 /** 39 * Abbreviations used when possible. 40 * @stable ICU 54 41 */ 42 UDAT_STYLE_SHORT, 43 44 /** 45 * Use the shortest possible form. 46 * @stable ICU 54 47 */ 48 UDAT_STYLE_NARROW, 49 50 /** 51 * The number of styles. 52 * @stable ICU 54 53 */ 54 UDAT_STYLE_COUNT 55 } UDateRelativeDateTimeFormatterStyle; 56 57 /** 58 * Represents the unit for formatting a relative date. e.g "in 5 days" 59 * or "in 3 months" 60 * @stable ICU 53 61 */ 62 typedef enum UDateRelativeUnit { 63 64 /** 65 * Seconds 66 * @stable ICU 53 67 */ 68 UDAT_RELATIVE_SECONDS, 69 70 /** 71 * Minutes 72 * @stable ICU 53 73 */ 74 UDAT_RELATIVE_MINUTES, 75 76 /** 77 * Hours 78 * @stable ICU 53 79 */ 80 UDAT_RELATIVE_HOURS, 81 82 /** 83 * Days 84 * @stable ICU 53 85 */ 86 UDAT_RELATIVE_DAYS, 87 88 /** 89 * Weeks 90 * @stable ICU 53 91 */ 92 UDAT_RELATIVE_WEEKS, 93 94 /** 95 * Months 96 * @stable ICU 53 97 */ 98 UDAT_RELATIVE_MONTHS, 99 100 /** 101 * Years 102 * @stable ICU 53 103 */ 104 UDAT_RELATIVE_YEARS, 105 106 /** 107 * Count of items in this enum. 108 * @stable ICU 53 109 */ 110 UDAT_RELATIVE_UNIT_COUNT 111 } UDateRelativeUnit; 112 113 /** 114 * Represents an absolute unit. 115 * @stable ICU 53 116 */ 117 typedef enum UDateAbsoluteUnit { 118 119 // Days of week have to remain together and in order from Sunday to 120 // Saturday. 121 /** 122 * Sunday 123 * @stable ICU 53 124 */ 125 UDAT_ABSOLUTE_SUNDAY, 126 127 /** 128 * Monday 129 * @stable ICU 53 130 */ 131 UDAT_ABSOLUTE_MONDAY, 132 133 /** 134 * Tuesday 135 * @stable ICU 53 136 */ 137 UDAT_ABSOLUTE_TUESDAY, 138 139 /** 140 * Wednesday 141 * @stable ICU 53 142 */ 143 UDAT_ABSOLUTE_WEDNESDAY, 144 145 /** 146 * Thursday 147 * @stable ICU 53 148 */ 149 UDAT_ABSOLUTE_THURSDAY, 150 151 /** 152 * Friday 153 * @stable ICU 53 154 */ 155 UDAT_ABSOLUTE_FRIDAY, 156 157 /** 158 * Saturday 159 * @stable ICU 53 160 */ 161 UDAT_ABSOLUTE_SATURDAY, 162 163 /** 164 * Day 165 * @stable ICU 53 166 */ 167 UDAT_ABSOLUTE_DAY, 168 169 /** 170 * Week 171 * @stable ICU 53 172 */ 173 UDAT_ABSOLUTE_WEEK, 174 175 /** 176 * Month 177 * @stable ICU 53 178 */ 179 UDAT_ABSOLUTE_MONTH, 180 181 /** 182 * Year 183 * @stable ICU 53 184 */ 185 UDAT_ABSOLUTE_YEAR, 186 187 /** 188 * Now 189 * @stable ICU 53 190 */ 191 UDAT_ABSOLUTE_NOW, 192 193 /** 194 * Count of items in this enum. 195 * @stable ICU 53 196 */ 197 UDAT_ABSOLUTE_UNIT_COUNT 198 } UDateAbsoluteUnit; 199 200 /** 201 * Represents a direction for an absolute unit e.g "Next Tuesday" 202 * or "Last Tuesday" 203 * @stable ICU 53 204 */ 205 typedef enum UDateDirection { 206 207 /** 208 * Two before. Not fully supported in every locale. 209 * @stable ICU 53 210 */ 211 UDAT_DIRECTION_LAST_2, 212 213 /** 214 * Last 215 * @stable ICU 53 216 */ 217 UDAT_DIRECTION_LAST, 218 219 /** 220 * This 221 * @stable ICU 53 222 */ 223 UDAT_DIRECTION_THIS, 224 225 /** 226 * Next 227 * @stable ICU 53 228 */ 229 UDAT_DIRECTION_NEXT, 230 231 /** 232 * Two after. Not fully supported in every locale. 233 * @stable ICU 53 234 */ 235 UDAT_DIRECTION_NEXT_2, 236 237 /** 238 * Plain, which means the absence of a qualifier. 239 * @stable ICU 53 240 */ 241 UDAT_DIRECTION_PLAIN, 242 243 /** 244 * Count of items in this enum. 245 * @stable ICU 53 246 */ 247 UDAT_DIRECTION_COUNT 248 } UDateDirection; 249 250 251 U_NAMESPACE_BEGIN 252 253 class RelativeDateTimeCacheData; 254 class SharedNumberFormat; 255 class SharedPluralRules; 256 class SharedBreakIterator; 257 class NumberFormat; 258 class UnicodeString; 259 260 /** 261 * Formats simple relative dates. There are two types of relative dates that 262 * it handles: 263 * <ul> 264 * <li>relative dates with a quantity e.g "in 5 days"</li> 265 * <li>relative dates without a quantity e.g "next Tuesday"</li> 266 * </ul> 267 * <p> 268 * This API is very basic and is intended to be a building block for more 269 * fancy APIs. The caller tells it exactly what to display in a locale 270 * independent way. While this class automatically provides the correct plural 271 * forms, the grammatical form is otherwise as neutral as possible. It is the 272 * caller's responsibility to handle cut-off logic such as deciding between 273 * displaying "in 7 days" or "in 1 week." This API supports relative dates 274 * involving one single unit. This API does not support relative dates 275 * involving compound units, 276 * e.g "in 5 days and 4 hours" nor does it support parsing. 277 * <p> 278 * This class is mostly thread safe and immutable with the following caveats: 279 * 1. The assignment operator violates Immutability. It must not be used 280 * concurrently with other operations. 281 * 2. Caller must not hold onto adopted pointers. 282 * <p> 283 * This class is not intended for public subclassing. 284 * <p> 285 * Here are some examples of use: 286 * <blockquote> 287 * <pre> 288 * UErrorCode status = U_ZERO_ERROR; 289 * UnicodeString appendTo; 290 * RelativeDateTimeFormatter fmt(status); 291 * // Appends "in 1 day" 292 * fmt.format( 293 * 1, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status); 294 * // Appends "in 3 days" 295 * fmt.format( 296 * 3, UDAT_DIRECTION_NEXT, UDAT_RELATIVE_DAYS, appendTo, status); 297 * // Appends "3.2 years ago" 298 * fmt.format( 299 * 3.2, UDAT_DIRECTION_LAST, UDAT_RELATIVE_YEARS, appendTo, status); 300 * // Appends "last Sunday" 301 * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 302 * // Appends "this Sunday" 303 * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 304 * // Appends "next Sunday" 305 * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 306 * // Appends "Sunday" 307 * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_SUNDAY, appendTo, status); 308 * 309 * // Appends "yesterday" 310 * fmt.format(UDAT_DIRECTION_LAST, UDAT_ABSOLUTE_DAY, appendTo, status); 311 * // Appends "today" 312 * fmt.format(UDAT_DIRECTION_THIS, UDAT_ABSOLUTE_DAY, appendTo, status); 313 * // Appends "tomorrow" 314 * fmt.format(UDAT_DIRECTION_NEXT, UDAT_ABSOLUTE_DAY, appendTo, status); 315 * // Appends "now" 316 * fmt.format(UDAT_DIRECTION_PLAIN, UDAT_ABSOLUTE_NOW, appendTo, status); 317 * 318 * </pre> 319 * </blockquote> 320 * <p> 321 * In the future, we may add more forms, such as abbreviated/short forms 322 * (3 secs ago), and relative day periods ("yesterday afternoon"), etc. 323 * 324 * The RelativeDateTimeFormatter class is not intended for public subclassing. 325 * 326 * @stable ICU 53 327 */ 328 class U_I18N_API RelativeDateTimeFormatter : public UObject { 329 public: 330 331 /** 332 * Create RelativeDateTimeFormatter with default locale. 333 * @stable ICU 53 334 */ 335 RelativeDateTimeFormatter(UErrorCode& status); 336 337 /** 338 * Create RelativeDateTimeFormatter with given locale. 339 * @stable ICU 53 340 */ 341 RelativeDateTimeFormatter(const Locale& locale, UErrorCode& status); 342 343 /** 344 * Create RelativeDateTimeFormatter with given locale and NumberFormat. 345 * 346 * @param locale the locale 347 * @param nfToAdopt Constructed object takes ownership of this pointer. 348 * It is an error for caller to delete this pointer or change its 349 * contents after calling this constructor. 350 * @status Any error is returned here. 351 * @stable ICU 53 352 */ 353 RelativeDateTimeFormatter( 354 const Locale& locale, NumberFormat *nfToAdopt, UErrorCode& status); 355 356 /** 357 * Create RelativeDateTimeFormatter with given locale, NumberFormat, 358 * and capitalization context. 359 * 360 * @param locale the locale 361 * @param nfToAdopt Constructed object takes ownership of this pointer. 362 * It is an error for caller to delete this pointer or change its 363 * contents after calling this constructor. Caller may pass NULL for 364 * this argument if they want default number format behavior. 365 * @param style the format style. The UDAT_RELATIVE bit field has no effect. 366 * @param capitalizationContext A value from UDisplayContext that pertains to 367 * capitalization. 368 * @status Any error is returned here. 369 * @stable ICU 54 370 */ 371 RelativeDateTimeFormatter( 372 const Locale& locale, 373 NumberFormat *nfToAdopt, 374 UDateRelativeDateTimeFormatterStyle style, 375 UDisplayContext capitalizationContext, 376 UErrorCode& status); 377 378 /** 379 * Copy constructor. 380 * @stable ICU 53 381 */ 382 RelativeDateTimeFormatter(const RelativeDateTimeFormatter& other); 383 384 /** 385 * Assignment operator. 386 * @stable ICU 53 387 */ 388 RelativeDateTimeFormatter& operator=( 389 const RelativeDateTimeFormatter& other); 390 391 /** 392 * Destructor. 393 * @stable ICU 53 394 */ 395 virtual ~RelativeDateTimeFormatter(); 396 397 /** 398 * Formats a relative date with a quantity such as "in 5 days" or 399 * "3 months ago" 400 * @param quantity The numerical amount e.g 5. This value is formatted 401 * according to this object's NumberFormat object. 402 * @param direction NEXT means a future relative date; LAST means a past 403 * relative date. If direction is anything else, this method sets 404 * status to U_ILLEGAL_ARGUMENT_ERROR. 405 * @param unit the unit e.g day? month? year? 406 * @param appendTo The string to which the formatted result will be 407 * appended 408 * @param status ICU error code returned here. 409 * @return appendTo 410 * @stable ICU 53 411 */ 412 UnicodeString& format( 413 double quantity, 414 UDateDirection direction, 415 UDateRelativeUnit unit, 416 UnicodeString& appendTo, 417 UErrorCode& status) const; 418 419 /** 420 * Formats a relative date without a quantity. 421 * @param direction NEXT, LAST, THIS, etc. 422 * @param unit e.g SATURDAY, DAY, MONTH 423 * @param appendTo The string to which the formatted result will be 424 * appended. If the value of direction is documented as not being fully 425 * supported in all locales then this method leaves appendTo unchanged if 426 * no format string is available. 427 * @param status ICU error code returned here. 428 * @return appendTo 429 * @stable ICU 53 430 */ 431 UnicodeString& format( 432 UDateDirection direction, 433 UDateAbsoluteUnit unit, 434 UnicodeString& appendTo, 435 UErrorCode& status) const; 436 437 /** 438 * Combines a relative date string and a time string in this object's 439 * locale. This is done with the same date-time separator used for the 440 * default calendar in this locale. 441 * 442 * @param relativeDateString the relative date, e.g 'yesterday' 443 * @param timeString the time e.g '3:45' 444 * @param appendTo concatenated date and time appended here 445 * @param status ICU error code returned here. 446 * @return appendTo 447 * @stable ICU 53 448 */ 449 UnicodeString& combineDateAndTime( 450 const UnicodeString& relativeDateString, 451 const UnicodeString& timeString, 452 UnicodeString& appendTo, 453 UErrorCode& status) const; 454 455 /** 456 * Returns the NumberFormat this object is using. 457 * 458 * @stable ICU 53 459 */ 460 const NumberFormat& getNumberFormat() const; 461 462 /** 463 * Returns the capitalization context. 464 * 465 * @stable ICU 54 466 */ 467 UDisplayContext getCapitalizationContext() const; 468 469 /** 470 * Returns the format style. 471 * 472 * @stable ICU 54 473 */ 474 UDateRelativeDateTimeFormatterStyle getFormatStyle() const; 475 476 private: 477 const RelativeDateTimeCacheData* fCache; 478 const SharedNumberFormat *fNumberFormat; 479 const SharedPluralRules *fPluralRules; 480 UDateRelativeDateTimeFormatterStyle fStyle; 481 UDisplayContext fContext; 482 const SharedBreakIterator *fOptBreakIterator; 483 Locale fLocale; 484 void init( 485 NumberFormat *nfToAdopt, 486 BreakIterator *brkIter, 487 UErrorCode &status); 488 void adjustForContext(UnicodeString &) const; 489 }; 490 491 U_NAMESPACE_END 492 493 #endif /* !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION*/ 494 #endif 495