1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *****************************************************************************************
5 * Copyright (C) 2016, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *****************************************************************************************
8 */
9 
10 #ifndef URELDATEFMT_H
11 #define URELDATEFMT_H
12 
13 #include "unicode/utypes.h"
14 
15 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
16 
17 #include "unicode/unum.h"
18 #include "unicode/udisplaycontext.h"
19 #include "unicode/localpointer.h"
20 #include "unicode/uformattedvalue.h"
21 
22 /**
23  * \file
24  * \brief C API: URelativeDateTimeFormatter, relative date formatting of unit + numeric offset.
25  *
26  * Provides simple formatting of relative dates, in two ways
27  * <ul>
28  *   <li>relative dates with a quantity e.g "in 5 days"</li>
29  *   <li>relative dates without a quantity e.g "next Tuesday"</li>
30  * </ul>
31  * <p>
32  * This does not provide compound formatting for multiple units,
33  * other than the ability to combine a time string with a relative date,
34  * as in "next Tuesday at 3:45 PM". It also does not provide support
35  * for determining which unit to use, such as deciding between "in 7 days"
36  * and "in 1 week".
37  *
38  * @stable ICU 57
39  */
40 
41 /**
42  * The formatting style
43  * @stable ICU 54
44  */
45 typedef enum UDateRelativeDateTimeFormatterStyle {
46   /**
47    * Everything spelled out.
48    * @stable ICU 54
49    */
50   UDAT_STYLE_LONG,
51 
52   /**
53    * Abbreviations used when possible.
54    * @stable ICU 54
55    */
56   UDAT_STYLE_SHORT,
57 
58   /**
59    * Use the shortest possible form.
60    * @stable ICU 54
61    */
62   UDAT_STYLE_NARROW,
63 
64 #ifndef U_HIDE_DEPRECATED_API
65     /**
66      * One more than the highest normal UDateRelativeDateTimeFormatterStyle value.
67      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
68      */
69     UDAT_STYLE_COUNT
70 #endif  /* U_HIDE_DEPRECATED_API */
71 } UDateRelativeDateTimeFormatterStyle;
72 
73 /**
74  * Represents the unit for formatting a relative date. e.g "in 5 days"
75  * or "next year"
76  * @stable ICU 57
77  */
78 typedef enum URelativeDateTimeUnit {
79     /**
80      * Specifies that relative unit is year, e.g. "last year",
81      * "in 5 years".
82      * @stable ICU 57
83      */
84     UDAT_REL_UNIT_YEAR,
85     /**
86      * Specifies that relative unit is quarter, e.g. "last quarter",
87      * "in 5 quarters".
88      * @stable ICU 57
89      */
90     UDAT_REL_UNIT_QUARTER,
91     /**
92      * Specifies that relative unit is month, e.g. "last month",
93      * "in 5 months".
94      * @stable ICU 57
95      */
96     UDAT_REL_UNIT_MONTH,
97     /**
98      * Specifies that relative unit is week, e.g. "last week",
99      * "in 5 weeks".
100      * @stable ICU 57
101      */
102     UDAT_REL_UNIT_WEEK,
103     /**
104      * Specifies that relative unit is day, e.g. "yesterday",
105      * "in 5 days".
106      * @stable ICU 57
107      */
108     UDAT_REL_UNIT_DAY,
109     /**
110      * Specifies that relative unit is hour, e.g. "1 hour ago",
111      * "in 5 hours".
112      * @stable ICU 57
113      */
114     UDAT_REL_UNIT_HOUR,
115     /**
116      * Specifies that relative unit is minute, e.g. "1 minute ago",
117      * "in 5 minutes".
118      * @stable ICU 57
119      */
120     UDAT_REL_UNIT_MINUTE,
121     /**
122      * Specifies that relative unit is second, e.g. "1 second ago",
123      * "in 5 seconds".
124      * @stable ICU 57
125      */
126     UDAT_REL_UNIT_SECOND,
127     /**
128      * Specifies that relative unit is Sunday, e.g. "last Sunday",
129      * "this Sunday", "next Sunday", "in 5 Sundays".
130      * @stable ICU 57
131      */
132     UDAT_REL_UNIT_SUNDAY,
133     /**
134      * Specifies that relative unit is Monday, e.g. "last Monday",
135      * "this Monday", "next Monday", "in 5 Mondays".
136      * @stable ICU 57
137      */
138     UDAT_REL_UNIT_MONDAY,
139     /**
140      * Specifies that relative unit is Tuesday, e.g. "last Tuesday",
141      * "this Tuesday", "next Tuesday", "in 5 Tuesdays".
142      * @stable ICU 57
143      */
144     UDAT_REL_UNIT_TUESDAY,
145     /**
146      * Specifies that relative unit is Wednesday, e.g. "last Wednesday",
147      * "this Wednesday", "next Wednesday", "in 5 Wednesdays".
148      * @stable ICU 57
149      */
150     UDAT_REL_UNIT_WEDNESDAY,
151     /**
152      * Specifies that relative unit is Thursday, e.g. "last Thursday",
153      * "this Thursday", "next Thursday", "in 5 Thursdays".
154      * @stable ICU 57
155      */
156     UDAT_REL_UNIT_THURSDAY,
157     /**
158      * Specifies that relative unit is Friday, e.g. "last Friday",
159      * "this Friday", "next Friday", "in 5 Fridays".
160      * @stable ICU 57
161      */
162     UDAT_REL_UNIT_FRIDAY,
163     /**
164      * Specifies that relative unit is Saturday, e.g. "last Saturday",
165      * "this Saturday", "next Saturday", "in 5 Saturdays".
166      * @stable ICU 57
167      */
168     UDAT_REL_UNIT_SATURDAY,
169 #ifndef U_HIDE_DEPRECATED_API
170     /**
171      * One more than the highest normal URelativeDateTimeUnit value.
172      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
173      */
174     UDAT_REL_UNIT_COUNT
175 #endif  /* U_HIDE_DEPRECATED_API */
176 } URelativeDateTimeUnit;
177 
178 /**
179  * FieldPosition and UFieldPosition selectors for format fields
180  * defined by RelativeDateTimeFormatter.
181  * @stable ICU 64
182  */
183 typedef enum URelativeDateTimeFormatterField {
184     /**
185      * Represents a literal text string, like "tomorrow" or "days ago".
186      * @stable ICU 64
187      */
188     UDAT_REL_LITERAL_FIELD,
189     /**
190      * Represents a number quantity, like "3" in "3 days ago".
191      * @stable ICU 64
192      */
193     UDAT_REL_NUMERIC_FIELD,
194 } URelativeDateTimeFormatterField;
195 
196 
197 /**
198  * Opaque URelativeDateTimeFormatter object for use in C programs.
199  * @stable ICU 57
200  */
201 struct URelativeDateTimeFormatter;
202 typedef struct URelativeDateTimeFormatter URelativeDateTimeFormatter;  /**< C typedef for struct URelativeDateTimeFormatter. @stable ICU 57 */
203 
204 
205 /**
206  * Open a new URelativeDateTimeFormatter object for a given locale using the
207  * specified width and capitalizationContext, along with a number formatter
208  * (if desired) to override the default formatter that would be used for
209  * display of numeric field offsets. The default formatter typically rounds
210  * toward 0 and has a minimum of 0 fraction digits and a maximum of 3
211  * fraction digits (i.e. it will show as many decimal places as necessary
212  * up to 3, without showing trailing 0s).
213  *
214  * @param locale
215  *          The locale
216  * @param nfToAdopt
217  *          A number formatter to set for this URelativeDateTimeFormatter
218  *          object (instead of the default decimal formatter). Ownership of
219  *          this UNumberFormat object will pass to the URelativeDateTimeFormatter
220  *          object (the URelativeDateTimeFormatter adopts the UNumberFormat),
221  *          which becomes responsible for closing it. If the caller wishes to
222  *          retain ownership of the UNumberFormat object, the caller must clone
223  *          it (with unum_clone) and pass the clone to ureldatefmt_open. May be
224  *          NULL to use the default decimal formatter.
225  * @param width
226  *          The width - wide, short, narrow, etc.
227  * @param capitalizationContext
228  *          A value from UDisplayContext that pertains to capitalization, e.g.
229  *          UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE.
230  * @param status
231  *          A pointer to a UErrorCode to receive any errors.
232  * @return
233  *          A pointer to a URelativeDateTimeFormatter object for the specified locale,
234  *          or NULL if an error occurred.
235  * @stable ICU 57
236  */
237 U_STABLE URelativeDateTimeFormatter* U_EXPORT2
238 ureldatefmt_open( const char*          locale,
239                   UNumberFormat*       nfToAdopt,
240                   UDateRelativeDateTimeFormatterStyle width,
241                   UDisplayContext      capitalizationContext,
242                   UErrorCode*          status );
243 
244 /**
245  * Close a URelativeDateTimeFormatter object. Once closed it may no longer be used.
246  * @param reldatefmt
247  *            The URelativeDateTimeFormatter object to close.
248  * @stable ICU 57
249  */
250 U_STABLE void U_EXPORT2
251 ureldatefmt_close(URelativeDateTimeFormatter *reldatefmt);
252 
253 struct UFormattedRelativeDateTime;
254 /**
255  * Opaque struct to contain the results of a URelativeDateTimeFormatter operation.
256  * @stable ICU 64
257  */
258 typedef struct UFormattedRelativeDateTime UFormattedRelativeDateTime;
259 
260 /**
261  * Creates an object to hold the result of a URelativeDateTimeFormatter
262  * operation. The object can be used repeatedly; it is cleared whenever
263  * passed to a format function.
264  *
265  * @param ec Set if an error occurs.
266  * @return A pointer needing ownership.
267  * @stable ICU 64
268  */
269 U_STABLE UFormattedRelativeDateTime* U_EXPORT2
270 ureldatefmt_openResult(UErrorCode* ec);
271 
272 /**
273  * Returns a representation of a UFormattedRelativeDateTime as a UFormattedValue,
274  * which can be subsequently passed to any API requiring that type.
275  *
276  * The returned object is owned by the UFormattedRelativeDateTime and is valid
277  * only as long as the UFormattedRelativeDateTime is present and unchanged in memory.
278  *
279  * You can think of this method as a cast between types.
280  *
281  * @param ufrdt The object containing the formatted string.
282  * @param ec Set if an error occurs.
283  * @return A UFormattedValue owned by the input object.
284  * @stable ICU 64
285  */
286 U_STABLE const UFormattedValue* U_EXPORT2
287 ureldatefmt_resultAsValue(const UFormattedRelativeDateTime* ufrdt, UErrorCode* ec);
288 
289 /**
290  * Releases the UFormattedRelativeDateTime created by ureldatefmt_openResult.
291  *
292  * @param ufrdt The object to release.
293  * @stable ICU 64
294  */
295 U_STABLE void U_EXPORT2
296 ureldatefmt_closeResult(UFormattedRelativeDateTime* ufrdt);
297 
298 
299 #if U_SHOW_CPLUSPLUS_API
300 
301 U_NAMESPACE_BEGIN
302 
303 /**
304  * \class LocalURelativeDateTimeFormatterPointer
305  * "Smart pointer" class, closes a URelativeDateTimeFormatter via ureldatefmt_close().
306  * For most methods see the LocalPointerBase base class.
307  *
308  * @see LocalPointerBase
309  * @see LocalPointer
310  * @stable ICU 57
311  */
312 U_DEFINE_LOCAL_OPEN_POINTER(LocalURelativeDateTimeFormatterPointer, URelativeDateTimeFormatter, ureldatefmt_close);
313 
314 /**
315  * \class LocalUFormattedRelativeDateTimePointer
316  * "Smart pointer" class, closes a UFormattedRelativeDateTime via ureldatefmt_closeResult().
317  * For most methods see the LocalPointerBase base class.
318  *
319  * @see LocalPointerBase
320  * @see LocalPointer
321  * @stable ICU 64
322  */
323 U_DEFINE_LOCAL_OPEN_POINTER(LocalUFormattedRelativeDateTimePointer, UFormattedRelativeDateTime, ureldatefmt_closeResult);
324 
325 U_NAMESPACE_END
326 
327 #endif
328 
329 /**
330  * Format a combination of URelativeDateTimeUnit and numeric
331  * offset using a numeric style, e.g. "1 week ago", "in 1 week",
332  * "5 weeks ago", "in 5 weeks".
333  *
334  * @param reldatefmt
335  *          The URelativeDateTimeFormatter object specifying the
336  *          format conventions.
337  * @param offset
338  *          The signed offset for the specified unit. This will
339  *          be formatted according to this object's UNumberFormat
340  *          object.
341  * @param unit
342  *          The unit to use when formatting the relative
343  *          date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY.
344  * @param result
345  *          A pointer to a buffer to receive the formatted result.
346  * @param resultCapacity
347  *          The maximum size of result.
348  * @param status
349  *          A pointer to a UErrorCode to receive any errors. In
350  *          case of error status, the contents of result are
351  *          undefined.
352  * @return
353  *          The length of the formatted result; may be greater
354  *          than resultCapacity, in which case an error is returned.
355  * @stable ICU 57
356  */
357 U_STABLE int32_t U_EXPORT2
358 ureldatefmt_formatNumeric( const URelativeDateTimeFormatter* reldatefmt,
359                     double                offset,
360                     URelativeDateTimeUnit unit,
361                     UChar*                result,
362                     int32_t               resultCapacity,
363                     UErrorCode*           status);
364 
365 /**
366  * Format a combination of URelativeDateTimeUnit and numeric
367  * offset using a numeric style, e.g. "1 week ago", "in 1 week",
368  * "5 weeks ago", "in 5 weeks".
369  *
370  * @param reldatefmt
371  *          The URelativeDateTimeFormatter object specifying the
372  *          format conventions.
373  * @param offset
374  *          The signed offset for the specified unit. This will
375  *          be formatted according to this object's UNumberFormat
376  *          object.
377  * @param unit
378  *          The unit to use when formatting the relative
379  *          date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY.
380  * @param result
381  *          A pointer to a UFormattedRelativeDateTime to populate.
382  * @param status
383  *          A pointer to a UErrorCode to receive any errors. In
384  *          case of error status, the contents of result are
385  *          undefined.
386  * @stable ICU 64
387  */
388 U_STABLE void U_EXPORT2
389 ureldatefmt_formatNumericToResult(
390     const URelativeDateTimeFormatter* reldatefmt,
391     double                            offset,
392     URelativeDateTimeUnit             unit,
393     UFormattedRelativeDateTime*       result,
394     UErrorCode*                       status);
395 
396 /**
397  * Format a combination of URelativeDateTimeUnit and numeric offset
398  * using a text style if possible, e.g. "last week", "this week",
399  * "next week", "yesterday", "tomorrow". Falls back to numeric
400  * style if no appropriate text term is available for the specified
401  * offset in the object's locale.
402  *
403  * @param reldatefmt
404  *          The URelativeDateTimeFormatter object specifying the
405  *          format conventions.
406  * @param offset
407  *          The signed offset for the specified unit.
408  * @param unit
409  *          The unit to use when formatting the relative
410  *          date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY.
411  * @param result
412  *          A pointer to a buffer to receive the formatted result.
413  * @param resultCapacity
414  *          The maximum size of result.
415  * @param status
416  *          A pointer to a UErrorCode to receive any errors. In
417  *          case of error status, the contents of result are
418  *          undefined.
419  * @return
420  *          The length of the formatted result; may be greater
421  *          than resultCapacity, in which case an error is returned.
422  * @stable ICU 57
423  */
424 U_STABLE int32_t U_EXPORT2
425 ureldatefmt_format( const URelativeDateTimeFormatter* reldatefmt,
426                     double                offset,
427                     URelativeDateTimeUnit unit,
428                     UChar*                result,
429                     int32_t               resultCapacity,
430                     UErrorCode*           status);
431 
432 /**
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.
438  *
439  * This method populates a UFormattedRelativeDateTime, which exposes more
440  * information than the string populated by format().
441  *
442  * @param reldatefmt
443  *          The URelativeDateTimeFormatter object specifying the
444  *          format conventions.
445  * @param offset
446  *          The signed offset for the specified unit.
447  * @param unit
448  *          The unit to use when formatting the relative
449  *          date, e.g. UDAT_REL_UNIT_WEEK, UDAT_REL_UNIT_FRIDAY.
450  * @param result
451  *          A pointer to a UFormattedRelativeDateTime to populate.
452  * @param status
453  *          A pointer to a UErrorCode to receive any errors. In
454  *          case of error status, the contents of result are
455  *          undefined.
456  * @stable ICU 64
457  */
458 U_STABLE void U_EXPORT2
459 ureldatefmt_formatToResult(
460     const URelativeDateTimeFormatter* reldatefmt,
461     double                            offset,
462     URelativeDateTimeUnit             unit,
463     UFormattedRelativeDateTime*       result,
464     UErrorCode*                       status);
465 
466 /**
467  * Combines a relative date string and a time string in this object's
468  * locale. This is done with the same date-time separator used for the
469  * default calendar in this locale to produce a result such as
470  * "yesterday at 3:45 PM".
471  *
472  * @param reldatefmt
473  *          The URelativeDateTimeFormatter object specifying the format conventions.
474  * @param relativeDateString
475  *          The relative date string.
476  * @param relativeDateStringLen
477  *          The length of relativeDateString; may be -1 if relativeDateString
478  *          is zero-terminated.
479  * @param timeString
480  *          The time string.
481  * @param timeStringLen
482  *          The length of timeString; may be -1 if timeString is zero-terminated.
483  * @param result
484  *          A pointer to a buffer to receive the formatted result.
485  * @param resultCapacity
486  *          The maximum size of result.
487  * @param status
488  *          A pointer to a UErrorCode to receive any errors. In case of error status,
489  *          the contents of result are undefined.
490  * @return
491  *          The length of the formatted result; may be greater than resultCapacity,
492  *          in which case an error is returned.
493  * @stable ICU 57
494  */
495 U_STABLE int32_t U_EXPORT2
496 ureldatefmt_combineDateAndTime( const URelativeDateTimeFormatter* reldatefmt,
497                     const UChar *     relativeDateString,
498                     int32_t           relativeDateStringLen,
499                     const UChar *     timeString,
500                     int32_t           timeStringLen,
501                     UChar*            result,
502                     int32_t           resultCapacity,
503                     UErrorCode*       status );
504 
505 #endif /* !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION */
506 
507 #endif
508