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