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