1/*
2*******************************************************************************
3* Copyright (C) 2007-2014, International Business Machines Corporation and    *
4* others. All Rights Reserved.                                                *
5*******************************************************************************
6*/
7
8#ifndef RELDTFMT_H
9#define RELDTFMT_H
10
11#include "unicode/utypes.h"
12
13/**
14 * \file
15 * \brief C++ API: Format and parse relative dates and times.
16 */
17
18#if !UCONFIG_NO_FORMATTING
19
20#include "unicode/datefmt.h"
21#include "unicode/smpdtfmt.h"
22#include "unicode/brkiter.h"
23
24U_NAMESPACE_BEGIN
25
26// forward declarations
27class DateFormatSymbols;
28class MessageFormat;
29
30// internal structure used for caching strings
31struct URelativeString;
32
33/**
34 * This class is normally accessed using the kRelative or k...Relative values of EStyle as
35 * parameters to DateFormat::createDateInstance.
36 *
37 * Example:
38 *     DateFormat *fullrelative = DateFormat::createDateInstance(DateFormat::kFullRelative, loc);
39 *
40 * @internal ICU 3.8
41 */
42
43class RelativeDateFormat : public DateFormat {
44public:
45    RelativeDateFormat( UDateFormatStyle timeStyle, UDateFormatStyle dateStyle, const Locale& locale, UErrorCode& status);
46
47    // overrides
48    /**
49     * Copy constructor.
50     * @internal ICU 3.8
51     */
52    RelativeDateFormat(const RelativeDateFormat&);
53
54    /**
55     * Assignment operator.
56     * @internal ICU 3.8
57     */
58    RelativeDateFormat& operator=(const RelativeDateFormat&);
59
60    /**
61     * Destructor.
62     * @internal ICU 3.8
63     */
64    virtual ~RelativeDateFormat();
65
66    /**
67     * Clone this Format object polymorphically. The caller owns the result and
68     * should delete it when done.
69     * @return    A copy of the object.
70     * @internal ICU 3.8
71     */
72    virtual Format* clone(void) const;
73
74    /**
75     * Return true if the given Format objects are semantically equal. Objects
76     * of different subclasses are considered unequal.
77     * @param other    the object to be compared with.
78     * @return         true if the given Format objects are semantically equal.
79     * @internal ICU 3.8
80     */
81    virtual UBool operator==(const Format& other) const;
82
83
84    using DateFormat::format;
85
86    /**
87     * Format a date or time, which is the standard millis since 24:00 GMT, Jan
88     * 1, 1970. Overrides DateFormat pure virtual method.
89     * <P>
90     * Example: using the US locale: "yyyy.MM.dd e 'at' HH:mm:ss zzz" ->>
91     * 1996.07.10 AD at 15:08:56 PDT
92     *
93     * @param cal       Calendar set to the date and time to be formatted
94     *                  into a date/time string.
95     * @param appendTo  Output parameter to receive result.
96     *                  Result is appended to existing contents.
97     * @param pos       The formatting position. On input: an alignment field,
98     *                  if desired. On output: the offsets of the alignment field.
99     * @return          Reference to 'appendTo' parameter.
100     * @internal ICU 3.8
101     */
102    virtual UnicodeString& format(  Calendar& cal,
103                                    UnicodeString& appendTo,
104                                    FieldPosition& pos) const;
105
106    /**
107     * Format an object to produce a string. This method handles Formattable
108     * objects with a UDate type. If a the Formattable object type is not a Date,
109     * then it returns a failing UErrorCode.
110     *
111     * @param obj       The object to format. Must be a Date.
112     * @param appendTo  Output parameter to receive result.
113     *                  Result is appended to existing contents.
114     * @param pos       On input: an alignment field, if desired.
115     *                  On output: the offsets of the alignment field.
116     * @param status    Output param filled with success/failure status.
117     * @return          Reference to 'appendTo' parameter.
118     * @internal ICU 3.8
119     */
120    virtual UnicodeString& format(const Formattable& obj,
121                                  UnicodeString& appendTo,
122                                  FieldPosition& pos,
123                                  UErrorCode& status) const;
124
125
126    /**
127     * Parse a date/time string beginning at the given parse position. For
128     * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date
129     * that is equivalent to Date(837039928046).
130     * <P>
131     * By default, parsing is lenient: If the input is not in the form used by
132     * this object's format method but can still be parsed as a date, then the
133     * parse succeeds. Clients may insist on strict adherence to the format by
134     * calling setLenient(false).
135     *
136     * @param text  The date/time string to be parsed
137     * @param cal   a Calendar set to the date and time to be formatted
138     *              into a date/time string.
139     * @param pos   On input, the position at which to start parsing; on
140     *              output, the position at which parsing terminated, or the
141     *              start position if the parse failed.
142     * @return      A valid UDate if the input could be parsed.
143     * @internal ICU 3.8
144     */
145    virtual void parse( const UnicodeString& text,
146                        Calendar& cal,
147                        ParsePosition& pos) const;
148
149    /**
150     * Parse a date/time string starting at the given parse position. For
151     * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date
152     * that is equivalent to Date(837039928046).
153     * <P>
154     * By default, parsing is lenient: If the input is not in the form used by
155     * this object's format method but can still be parsed as a date, then the
156     * parse succeeds. Clients may insist on strict adherence to the format by
157     * calling setLenient(false).
158     *
159     * @see DateFormat::setLenient(boolean)
160     *
161     * @param text  The date/time string to be parsed
162     * @param pos   On input, the position at which to start parsing; on
163     *              output, the position at which parsing terminated, or the
164     *              start position if the parse failed.
165     * @return      A valid UDate if the input could be parsed.
166     * @internal ICU 3.8
167     */
168    UDate parse( const UnicodeString& text,
169                 ParsePosition& pos) const;
170
171
172    /**
173     * Parse a date/time string. For example, a time text "07/10/96 4:5 PM, PDT"
174     * will be parsed into a UDate that is equivalent to Date(837039928046).
175     * Parsing begins at the beginning of the string and proceeds as far as
176     * possible.  Assuming no parse errors were encountered, this function
177     * doesn't return any information about how much of the string was consumed
178     * by the parsing.  If you need that information, use the version of
179     * parse() that takes a ParsePosition.
180     *
181     * @param text  The date/time string to be parsed
182     * @param status Filled in with U_ZERO_ERROR if the parse was successful, and with
183     *              an error value if there was a parse error.
184     * @return      A valid UDate if the input could be parsed.
185     * @internal ICU 3.8
186     */
187    virtual UDate parse( const UnicodeString& text,
188                        UErrorCode& status) const;
189
190    /**
191     * Return a single pattern string generated by combining the patterns for the
192     * date and time formatters associated with this object.
193     * @param result Output param to receive the pattern.
194     * @return       A reference to 'result'.
195     * @internal ICU 4.2 technology preview
196     */
197    virtual UnicodeString& toPattern(UnicodeString& result, UErrorCode& status) const;
198
199    /**
200     * Get the date pattern for the the date formatter associated with this object.
201     * @param result Output param to receive the date pattern.
202     * @return       A reference to 'result'.
203     * @internal ICU 4.2 technology preview
204     */
205    virtual UnicodeString& toPatternDate(UnicodeString& result, UErrorCode& status) const;
206
207    /**
208     * Get the time pattern for the the time formatter associated with this object.
209     * @param result Output param to receive the time pattern.
210     * @return       A reference to 'result'.
211     * @internal ICU 4.2 technology preview
212     */
213    virtual UnicodeString& toPatternTime(UnicodeString& result, UErrorCode& status) const;
214
215    /**
216     * Apply the given unlocalized date & time pattern strings to this relative date format.
217     * (i.e., after this call, this formatter will format dates and times according to
218     * the new patterns)
219     *
220     * @param datePattern   The date pattern to be applied.
221     * @param timePattern   The time pattern to be applied.
222     * @internal ICU 4.2 technology preview
223     */
224    virtual void applyPatterns(const UnicodeString& datePattern, const UnicodeString& timePattern, UErrorCode &status);
225
226    /**
227     * Gets the date/time formatting symbols (this is an object carrying
228     * the various strings and other symbols used in formatting: e.g., month
229     * names and abbreviations, time zone names, AM/PM strings, etc.)
230     * @return a copy of the date-time formatting data associated
231     * with this date-time formatter.
232     * @internal ICU 4.8
233     */
234    virtual const DateFormatSymbols* getDateFormatSymbols(void) const;
235
236    /* Cannot use #ifndef U_HIDE_DRAFT_API for the following draft method since it is virtual */
237    /**
238     * Set a particular UDisplayContext value in the formatter, such as
239     * UDISPCTX_CAPITALIZATION_FOR_STANDALONE. Note: For getContext, see
240     * DateFormat.
241     * @param value The UDisplayContext value to set.
242     * @param status Input/output status. If at entry this indicates a failure
243     *               status, the function will do nothing; otherwise this will be
244     *               updated with any new status from the function.
245     * @internal ICU 53
246     */
247    virtual void setContext(UDisplayContext value, UErrorCode& status);
248
249private:
250    SimpleDateFormat *fDateTimeFormatter;
251    UnicodeString fDatePattern;
252    UnicodeString fTimePattern;
253    MessageFormat *fCombinedFormat; //  the {0} {1} format.
254
255    UDateFormatStyle fDateStyle;
256    Locale  fLocale;
257
258    int32_t fDayMin;    // day id of lowest #
259    int32_t fDayMax;    // day id of highest #
260    int32_t fDatesLen;    // Length of array
261    URelativeString *fDates; // array of strings
262
263    UBool fCombinedHasDateAtStart;
264    UBool fCapitalizationInfoSet;
265    UBool fCapitalizationOfRelativeUnitsForUIListMenu;
266    UBool fCapitalizationOfRelativeUnitsForStandAlone;
267    BreakIterator* fCapitalizationBrkIter;
268
269    /**
270     * Get the string at a specific offset.
271     * @param day day offset ( -1, 0, 1, etc.. )
272     * @param len on output, length of string.
273     * @return the string, or NULL if none at that location.
274     */
275    const UChar *getStringForDay(int32_t day, int32_t &len, UErrorCode &status) const;
276
277    /**
278     * Load the Date string array
279     */
280    void loadDates(UErrorCode &status);
281
282    /**
283     * Set fCapitalizationOfRelativeUnitsForUIListMenu, fCapitalizationOfRelativeUnitsForStandAlone
284     */
285    void initCapitalizationContextInfo(const Locale& thelocale);
286
287    /**
288     * @return the number of days in "until-now"
289     */
290    static int32_t dayDifference(Calendar &until, UErrorCode &status);
291
292    /**
293     * initializes fCalendar from parameters.  Returns fCalendar as a convenience.
294     * @param adoptZone  Zone to be adopted, or NULL for TimeZone::createDefault().
295     * @param locale Locale of the calendar
296     * @param status Error code
297     * @return the newly constructed fCalendar
298     * @internal ICU 3.8
299     */
300    Calendar* initializeCalendar(TimeZone* adoptZone, const Locale& locale, UErrorCode& status);
301
302public:
303    /**
304     * Return the class ID for this class. This is useful only for comparing to
305     * a return value from getDynamicClassID(). For example:
306     * <pre>
307     * .   Base* polymorphic_pointer = createPolymorphicObject();
308     * .   if (polymorphic_pointer->getDynamicClassID() ==
309     * .       erived::getStaticClassID()) ...
310     * </pre>
311     * @return          The class ID for all objects of this class.
312     * @internal ICU 3.8
313     */
314    U_I18N_API static UClassID U_EXPORT2 getStaticClassID(void);
315
316    /**
317     * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
318     * method is to implement a simple version of RTTI, since not all C++
319     * compilers support genuine RTTI. Polymorphic operator==() and clone()
320     * methods call this method.
321     *
322     * @return          The class ID for this object. All objects of a
323     *                  given class have the same class ID.  Objects of
324     *                  other classes have different class IDs.
325     * @internal ICU 3.8
326     */
327    virtual UClassID getDynamicClassID(void) const;
328};
329
330
331U_NAMESPACE_END
332
333#endif /* #if !UCONFIG_NO_FORMATTING */
334
335#endif // RELDTFMT_H
336//eof
337