Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
dtitvfmt.h1155 linesDownload Raw Back to unicode
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3/********************************************************************************
4* Copyright (C) 2008-2016, International Business Machines Corporation and
5* others. All Rights Reserved.
6*******************************************************************************
7*
8* File DTITVFMT.H
9*
10*******************************************************************************
11*/
12
13#ifndef __DTITVFMT_H__
14#define __DTITVFMT_H__
15
16
17#include "unicode/utypes.h"
18
19#if U_SHOW_CPLUSPLUS_API
20
21/**
22 * \file
23 * \brief C++ API: Format and parse date interval in a language-independent manner.
24 */
25
26#if !UCONFIG_NO_FORMATTING
27
28#include "unicode/ucal.h"
29#include "unicode/smpdtfmt.h"
30#include "unicode/dtintrv.h"
31#include "unicode/dtitvinf.h"
32#include "unicode/dtptngen.h"
33#include "unicode/formattedvalue.h"
34
35U_NAMESPACE_BEGIN
36
37
38class FormattedDateIntervalData;
39class DateIntervalFormat;
40
41/**
42 * An immutable class containing the result of a date interval formatting operation.
43 *
44 * Instances of this class are immutable and thread-safe.
45 *
46 * When calling nextPosition():
47 * The fields are returned from left to right. The special field category
48 * UFIELD_CATEGORY_DATE_INTERVAL_SPAN is used to indicate which datetime
49 * primitives came from which arguments: 0 means fromCalendar, and 1 means
50 * toCalendar. The span category will always occur before the
51 * corresponding fields in UFIELD_CATEGORY_DATE
52 * in the nextPosition() iterator.
53 *
54 * Not intended for public subclassing.
55 *
56 * @stable ICU 64
57 */
58class U_I18N_API FormattedDateInterval : public UMemory, public FormattedValue {
59  public:
60    /**
61     * Default constructor; makes an empty FormattedDateInterval.
62     * @stable ICU 64
63     */
64    FormattedDateInterval() : fData(nullptr), fErrorCode(U_INVALID_STATE_ERROR) {}
65
66    /**
67     * Move constructor: Leaves the source FormattedDateInterval in an undefined state.
68     * @stable ICU 64
69     */
70    FormattedDateInterval(FormattedDateInterval&& src) U_NOEXCEPT;
71
72    /**
73     * Destruct an instance of FormattedDateInterval.
74     * @stable ICU 64
75     */
76    virtual ~FormattedDateInterval() U_OVERRIDE;
77
78    /** Copying not supported; use move constructor instead. */
79    FormattedDateInterval(const FormattedDateInterval&) = delete;
80
81    /** Copying not supported; use move assignment instead. */
82    FormattedDateInterval& operator=(const FormattedDateInterval&) = delete;
83
84    /**
85     * Move assignment: Leaves the source FormattedDateInterval in an undefined state.
86     * @stable ICU 64
87     */
88    FormattedDateInterval& operator=(FormattedDateInterval&& src) U_NOEXCEPT;
89
90    /** @copydoc FormattedValue::toString() */
91    UnicodeString toString(UErrorCode& status) const U_OVERRIDE;
92
93    /** @copydoc FormattedValue::toTempString() */
94    UnicodeString toTempString(UErrorCode& status) const U_OVERRIDE;
95
96    /** @copydoc FormattedValue::appendTo() */
97    Appendable &appendTo(Appendable& appendable, UErrorCode& status) const U_OVERRIDE;
98
99    /** @copydoc FormattedValue::nextPosition() */
100    UBool nextPosition(ConstrainedFieldPosition& cfpos, UErrorCode& status) const U_OVERRIDE;
101
102  private:
103    FormattedDateIntervalData *fData;
104    UErrorCode fErrorCode;
105    explicit FormattedDateInterval(FormattedDateIntervalData *results)
106        : fData(results), fErrorCode(U_ZERO_ERROR) {}
107    explicit FormattedDateInterval(UErrorCode errorCode)
108        : fData(nullptr), fErrorCode(errorCode) {}
109    friend class DateIntervalFormat;
110};
111
112
113/**
114 * DateIntervalFormat is a class for formatting and parsing date
115 * intervals in a language-independent manner.
116 * Only formatting is supported, parsing is not supported.
117 *
118 * <P>
119 * Date interval means from one date to another date,
120 * for example, from "Jan 11, 2008" to "Jan 18, 2008".
121 * We introduced class DateInterval to represent it.
122 * DateInterval is a pair of UDate, which is
123 * the standard milliseconds since 24:00 GMT, Jan 1, 1970.
124 *
125 * <P>
126 * DateIntervalFormat formats a DateInterval into
127 * text as compactly as possible.
128 * For example, the date interval format from "Jan 11, 2008" to "Jan 18,. 2008"
129 * is "Jan 11-18, 2008" for English.
130 * And it parses text into DateInterval,
131 * although initially, parsing is not supported.
132 *
133 * <P>
134 * There is no structural information in date time patterns.
135 * For any punctuations and string literals inside a date time pattern,
136 * we do not know whether it is just a separator, or a prefix, or a suffix.
137 * Without such information, so, it is difficult to generate a sub-pattern
138 * (or super-pattern) by algorithm.
139 * So, formatting a DateInterval is pattern-driven. It is very
140 * similar to formatting in SimpleDateFormat.
141 * We introduce class DateIntervalInfo to save date interval
142 * patterns, similar to date time pattern in SimpleDateFormat.
143 *
144 * <P>
145 * Logically, the interval patterns are mappings
146 * from (skeleton, the_largest_different_calendar_field)
147 * to (date_interval_pattern).
148 *
149 * <P>
150 * A skeleton
151 * <ol>
152 * <li>
153 * only keeps the field pattern letter and ignores all other parts
154 * in a pattern, such as space, punctuations, and string literals.
155 * </li>
156 * <li>
157 * hides the order of fields.
158 * </li>
159 * <li>
160 * might hide a field's pattern letter length.
161 * </li>
162 * </ol>
163 *
164 * For those non-digit calendar fields, the pattern letter length is
165 * important, such as MMM, MMMM, and MMMMM; EEE and EEEE,
166 * and the field's pattern letter length is honored.
167 *
168 * For the digit calendar fields,  such as M or MM, d or dd, yy or yyyy,
169 * the field pattern length is ignored and the best match, which is defined
170 * in date time patterns, will be returned without honor the field pattern
171 * letter length in skeleton.
172 *
173 * <P>
174 * The calendar fields we support for interval formatting are:
175 * year, month, date, day-of-week, am-pm, hour, hour-of-day, minute, second,
176 * and millisecond.
177 * (though we do not currently have specific intervalFormat date for skeletons
178 * with seconds and millisecond).
179 * Those calendar fields can be defined in the following order:
180 * year >  month > date > hour (in day) >  minute > second > millisecond
181 *
182 * The largest different calendar fields between 2 calendars is the
183 * first different calendar field in above order.
184 *
185 * For example: the largest different calendar fields between "Jan 10, 2007"
186 * and "Feb 20, 2008" is year.
187 *
188 * <P>
189 * For other calendar fields, the compact interval formatting is not
190 * supported. And the interval format will be fall back to fall-back
191 * patterns, which is mostly "{date0} - {date1}".
192 *
193 * <P>
194 * There is a set of pre-defined static skeleton strings.
195 * There are pre-defined interval patterns for those pre-defined skeletons
196 * in locales' resource files.
197 * For example, for a skeleton UDAT_YEAR_ABBR_MONTH_DAY, which is  &quot;yMMMd&quot;,
198 * in  en_US, if the largest different calendar field between date1 and date2
199 * is &quot;year&quot;, the date interval pattern  is &quot;MMM d, yyyy - MMM d, yyyy&quot;,
200 * such as &quot;Jan 10, 2007 - Jan 10, 2008&quot;.
201 * If the largest different calendar field between date1 and date2 is &quot;month&quot;,
202 * the date interval pattern is &quot;MMM d - MMM d, yyyy&quot;,
203 * such as &quot;Jan 10 - Feb 10, 2007&quot;.
204 * If the largest different calendar field between date1 and date2 is &quot;day&quot;,
205 * the date interval pattern is &quot;MMM d-d, yyyy&quot;, such as &quot;Jan 10-20, 2007&quot;.
206 *
207 * For date skeleton, the interval patterns when year, or month, or date is
208 * different are defined in resource files.
209 * For time skeleton, the interval patterns when am/pm, or hour, or minute is
210 * different are defined in resource files.
211 *
212 * <P>
213 * If a skeleton is not found in a locale's DateIntervalInfo, which means
214 * the interval patterns for the skeleton is not defined in resource file,
215 * the interval pattern will falls back to the interval "fallback" pattern
216 * defined in resource file.
217 * If the interval "fallback" pattern is not defined, the default fall-back
218 * is "{date0} - {data1}".
219 *
220 * <P>
221 * For the combination of date and time,
222 * The rule to generate interval patterns are:
223 * <ol>
224 * <li>
225 *    when the year, month, or day differs, falls back to fall-back
226 *    interval pattern, which mostly is the concatenate the two original
227 *    expressions with a separator between,
228 *    For example, interval pattern from "Jan 10, 2007 10:10 am"
229 *    to "Jan 11, 2007 10:10am" is
230 *    "Jan 10, 2007 10:10 am - Jan 11, 2007 10:10am"
231 * </li>
232 * <li>
233 *    otherwise, present the date followed by the range expression
234 *    for the time.
235 *    For example, interval pattern from "Jan 10, 2007 10:10 am"
236 *    to "Jan 10, 2007 11:10am" is "Jan 10, 2007 10:10 am - 11:10am"
237 * </li>
238 * </ol>
239 *
240 *
241 * <P>
242 * If two dates are the same, the interval pattern is the single date pattern.
243 * For example, interval pattern from "Jan 10, 2007" to "Jan 10, 2007" is
244 * "Jan 10, 2007".
245 *
246 * Or if the presenting fields between 2 dates have the exact same values,
247 * the interval pattern is the  single date pattern.
248 * For example, if user only requests year and month,
249 * the interval pattern from "Jan 10, 2007" to "Jan 20, 2007" is "Jan 2007".
250 *
251 * <P>
252 * DateIntervalFormat needs the following information for correct
253 * formatting: time zone, calendar type, pattern, date format symbols,
254 * and date interval patterns.
255 * It can be instantiated in 2 ways:
256 * <ol>
257 * <li>
258 *    create an instance using default or given locale plus given skeleton.
259 *    Users are encouraged to created date interval formatter this way and
260 *    to use the pre-defined skeleton macros, such as
261 *    UDAT_YEAR_NUM_MONTH, which consists the calendar fields and
262 *    the format style.
263 * </li>
264 * <li>
265 *    create an instance using default or given locale plus given skeleton
266 *    plus a given DateIntervalInfo.
267 *    This factory method is for powerful users who want to provide their own
268 *    interval patterns.
269 *    Locale provides the timezone, calendar, and format symbols information.
270 *    Local plus skeleton provides full pattern information.
271 *    DateIntervalInfo provides the date interval patterns.
272 * </li>
273 * </ol>
274 *
275 * <P>
276 * For the calendar field pattern letter, such as G, y, M, d, a, h, H, m, s etc.
277 * DateIntervalFormat uses the same syntax as that of
278 * DateTime format.
279 *
280 * <P>
281 * Code Sample: general usage
282 * <pre>
283 * \code
284 *   // the date interval object which the DateIntervalFormat formats on
285 *   // and parses into
286 *   DateInterval*  dtInterval = new DateInterval(1000*3600*24, 1000*3600*24*2);
287 *   UErrorCode status = U_ZERO_ERROR;
288 *   DateIntervalFormat* dtIntervalFmt = DateIntervalFormat::createInstance(
289 *                           UDAT_YEAR_MONTH_DAY,
290 *                           Locale("en", "GB", ""), status);
291 *   UnicodeUnicodeString dateIntervalString;
292 *   FieldPosition pos = 0;
293 *   // formatting
294 *   dtIntervalFmt->format(dtInterval, dateIntervalUnicodeString, pos, status);
295 *   delete dtIntervalFmt;
296 * \endcode
297 * </pre>
298 */
299class U_I18N_API DateIntervalFormat : public Format {
300public:
301
302    /**
303     * Construct a DateIntervalFormat from skeleton and  the default locale.
304     *
305     * This is a convenient override of
306     * createInstance(const UnicodeString& skeleton, const Locale& locale,
307     *                UErrorCode&)
308     * with the value of locale as default locale.
309     *
310     * @param skeleton  the skeleton on which interval format based.
311     * @param status    output param set to success/failure code on exit
312     * @return          a date time interval formatter which the caller owns.
313     * @stable ICU 4.0
314     */
315    static DateIntervalFormat* U_EXPORT2 createInstance(
316                                               const UnicodeString& skeleton,
317                                               UErrorCode& status);
318
319    /**
320     * Construct a DateIntervalFormat from skeleton and a given locale.
321     * <P>
322     * In this factory method,
323     * the date interval pattern information is load from resource files.
324     * Users are encouraged to created date interval formatter this way and
325     * to use the pre-defined skeleton macros.
326     *
327     * <P>
328     * There are pre-defined skeletons (defined in udate.h) having predefined
329     * interval patterns in resource files.
330     * Users are encouraged to use those macros.
331     * For example:
332     * DateIntervalFormat::createInstance(UDAT_MONTH_DAY, status)
333     *
334     * The given Locale provides the interval patterns.
335     * For example, for en_GB, if skeleton is UDAT_YEAR_ABBR_MONTH_WEEKDAY_DAY,
336     * which is "yMMMEEEd",
337     * the interval patterns defined in resource file to above skeleton are:
338     * "EEE, d MMM, yyyy - EEE, d MMM, yyyy" for year differs,
339     * "EEE, d MMM - EEE, d MMM, yyyy" for month differs,
340     * "EEE, d - EEE, d MMM, yyyy" for day differs,
341     * @param skeleton  the skeleton on which the interval format is based.
342     * @param locale    the given locale
343     * @param status    output param set to success/failure code on exit
344     * @return          a date time interval formatter which the caller owns.
345     * @stable ICU 4.0
346	 * <p>
347	 * <h4>Sample code</h4>
348	 * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtPreDefined1
349	 * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtPreDefined
350	 * <p>
351     */
352
353    static DateIntervalFormat* U_EXPORT2 createInstance(
354                                               const UnicodeString& skeleton,
355                                               const Locale& locale,
356                                               UErrorCode& status);
357
358    /**
359     * Construct a DateIntervalFormat from skeleton
360     *  DateIntervalInfo, and default locale.
361     *
362     * This is a convenient override of
363     * createInstance(const UnicodeString& skeleton, const Locale& locale,
364     *                const DateIntervalInfo& dtitvinf, UErrorCode&)
365     * with the locale value as default locale.
366     *
367     * @param skeleton  the skeleton on which interval format based.
368     * @param dtitvinf  the DateIntervalInfo object.
369     * @param status    output param set to success/failure code on exit
370     * @return          a date time interval formatter which the caller owns.
371     * @stable ICU 4.0
372     */
373    static DateIntervalFormat* U_EXPORT2 createInstance(
374                                              const UnicodeString& skeleton,
375                                              const DateIntervalInfo& dtitvinf,
376                                              UErrorCode& status);
377
378    /**
379     * Construct a DateIntervalFormat from skeleton
380     * a DateIntervalInfo, and the given locale.
381     *
382     * <P>
383     * In this factory method, user provides its own date interval pattern
384     * information, instead of using those pre-defined data in resource file.
385     * This factory method is for powerful users who want to provide their own
386     * interval patterns.
387     * <P>
388     * There are pre-defined skeletons (defined in udate.h) having predefined
389     * interval patterns in resource files.
390     * Users are encouraged to use those macros.
391     * For example:
392     * DateIntervalFormat::createInstance(UDAT_MONTH_DAY, status)
393     *
394     * The DateIntervalInfo provides the interval patterns.
395     * and the DateIntervalInfo ownership remains to the caller.
396     *
397     * User are encouraged to set default interval pattern in DateIntervalInfo
398     * as well, if they want to set other interval patterns ( instead of
399     * reading the interval patterns from resource files).
400     * When the corresponding interval pattern for a largest calendar different
401     * field is not found ( if user not set it ), interval format fallback to
402     * the default interval pattern.
403     * If user does not provide default interval pattern, it fallback to
404     * "{date0} - {date1}"
405     *
406     * @param skeleton  the skeleton on which interval format based.
407     * @param locale    the given locale
408     * @param dtitvinf  the DateIntervalInfo object.
409     * @param status    output param set to success/failure code on exit
410     * @return          a date time interval formatter which the caller owns.
411     * @stable ICU 4.0
412	 * <p>
413	 * <h4>Sample code</h4>
414	 * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtPreDefined1
415	 * \snippet samples/dtitvfmtsample/dtitvfmtsample.cpp dtitvfmtCustomized
416	 * <p>
417     */
418    static DateIntervalFormat* U_EXPORT2 createInstance(
419                                              const UnicodeString& skeleton,
420                                              const Locale& locale,
421                                              const DateIntervalInfo& dtitvinf,
422                                              UErrorCode& status);
423
424    /**
425     * Destructor.
426     * @stable ICU 4.0
427     */
428    virtual ~DateIntervalFormat();
429
430    /**
431     * Clone this Format object polymorphically. The caller owns the result and
432     * should delete it when done.
433     * @return    A copy of the object.
434     * @stable ICU 4.0
435     */
436    virtual DateIntervalFormat* clone() const;
437
438    /**
439     * Return true if the given Format objects are semantically equal. Objects
440     * of different subclasses are considered unequal.
441     * @param other    the object to be compared with.
442     * @return         true if the given Format objects are semantically equal.
443     * @stable ICU 4.0
444     */
445    virtual UBool operator==(const Format& other) const;
446
447    /**
448     * Return true if the given Format objects are not semantically equal.
449     * Objects of different subclasses are considered unequal.
450     * @param other the object to be compared with.
451     * @return      true if the given Format objects are not semantically equal.
452     * @stable ICU 4.0
453     */
454    UBool operator!=(const Format& other) const;
455
456
457    using Format::format;
458
459    /**
460     * Format an object to produce a string. This method handles Formattable
461     * objects with a DateInterval type.
462     * If a the Formattable object type is not a DateInterval,
463     * then it returns a failing UErrorCode.
464     *
465     * @param obj               The object to format.
466     *                          Must be a DateInterval.
467     * @param appendTo          Output parameter to receive result.
468     *                          Result is appended to existing contents.
469     * @param fieldPosition     On input: an alignment field, if desired.
470     *                          On output: the offsets of the alignment field.
471     *                          There may be multiple instances of a given field type
472     *                          in an interval format; in this case the fieldPosition
473     *                          offsets refer to the first instance.
474     * @param status            Output param filled with success/failure status.
475     * @return                  Reference to 'appendTo' parameter.
476     * @stable ICU 4.0
477     */
478    virtual UnicodeString& format(const Formattable& obj,
479                                  UnicodeString& appendTo,
480                                  FieldPosition& fieldPosition,
481                                  UErrorCode& status) const ;
482
483
484
485    /**
486     * Format a DateInterval to produce a string.
487     *
488     * @param dtInterval        DateInterval to be formatted.
489     * @param appendTo          Output parameter to receive result.
490     *                          Result is appended to existing contents.
491     * @param fieldPosition     On input: an alignment field, if desired.
492     *                          On output: the offsets of the alignment field.
493     *                          There may be multiple instances of a given field type
494     *                          in an interval format; in this case the fieldPosition
495     *                          offsets refer to the first instance.
496     * @param status            Output param filled with success/failure status.
497     * @return                  Reference to 'appendTo' parameter.
498     * @stable ICU 4.0
499     */
500    UnicodeString& format(const DateInterval* dtInterval,
501                          UnicodeString& appendTo,
502                          FieldPosition& fieldPosition,
503                          UErrorCode& status) const ;
504
505    /**
506     * Format a DateInterval to produce a FormattedDateInterval.
507     *
508     * The FormattedDateInterval exposes field information about the formatted string.
509     *
510     * @param dtInterval        DateInterval to be formatted.
511     * @param status            Set if an error occurs.
512     * @return                  A FormattedDateInterval containing the format result.
513     * @stable ICU 64
514     */
515    FormattedDateInterval formatToValue(
516        const DateInterval& dtInterval,
517        UErrorCode& status) const;
518
519    /**
520     * Format 2 Calendars to produce a string.
521     *
522     * Note: "fromCalendar" and "toCalendar" are not const,
523     * since calendar is not const in  SimpleDateFormat::format(Calendar&),
524     *
525     * @param fromCalendar      calendar set to the from date in date interval
526     *                          to be formatted into date interval string
527     * @param toCalendar        calendar set to the to date in date interval
528     *                          to be formatted into date interval string
529     * @param appendTo          Output parameter to receive result.
530     *                          Result is appended to existing contents.
531     * @param fieldPosition     On input: an alignment field, if desired.
532     *                          On output: the offsets of the alignment field.
533     *                          There may be multiple instances of a given field type
534     *                          in an interval format; in this case the fieldPosition
535     *                          offsets refer to the first instance.
536     * @param status            Output param filled with success/failure status.
537     *                          Caller needs to make sure it is SUCCESS
538     *                          at the function entrance
539     * @return                  Reference to 'appendTo' parameter.
540     * @stable ICU 4.0
541     */
542    UnicodeString& format(Calendar& fromCalendar,
543                          Calendar& toCalendar,
544                          UnicodeString& appendTo,
545                          FieldPosition& fieldPosition,
546                          UErrorCode& status) const ;
547
548    /**
549     * Format 2 Calendars to produce a FormattedDateInterval.
550     *
551     * The FormattedDateInterval exposes field information about the formatted string.
552     *
553     * Note: "fromCalendar" and "toCalendar" are not const,
554     * since calendar is not const in  SimpleDateFormat::format(Calendar&),
555     *
556     * @param fromCalendar      calendar set to the from date in date interval
557     *                          to be formatted into date interval string
558     * @param toCalendar        calendar set to the to date in date interval
559     *                          to be formatted into date interval string
560     * @param status            Set if an error occurs.
561     * @return                  A FormattedDateInterval containing the format result.
562     * @stable ICU 64
563     */
564    FormattedDateInterval formatToValue(
565        Calendar& fromCalendar,
566        Calendar& toCalendar,
567        UErrorCode& status) const;
568
569    /**
570     * Date interval parsing is not supported. Please do not use.
571     * <P>
572     * This method should handle parsing of
573     * date time interval strings into Formattable objects with
574     * DateInterval type, which is a pair of UDate.
575     * <P>
576     * Before calling, set parse_pos.index to the offset you want to start
577     * parsing at in the source. After calling, parse_pos.index is the end of
578     * the text you parsed. If error occurs, index is unchanged.
579     * <P>
580     * When parsing, leading whitespace is discarded (with a successful parse),
581     * while trailing whitespace is left as is.
582     * <P>
583     * See Format::parseObject() for more.
584     *
585     * @param source    The string to be parsed into an object.
586     * @param result    Formattable to be set to the parse result.
587     *                  If parse fails, return contents are undefined.
588     * @param parse_pos The position to start parsing at. Since no parsing
589     *                  is supported, upon return this param is unchanged.
590     * @return          A newly created Formattable* object, or NULL
591     *                  on failure.  The caller owns this and should
592     *                  delete it when done.
593     * @internal ICU 4.0
594     */
595    virtual void parseObject(const UnicodeString& source,
596                             Formattable& result,
597                             ParsePosition& parse_pos) const;
598
599
600    /**
601     * Gets the date time interval patterns.
602     * @return the date time interval patterns associated with
603     * this date interval formatter.
604     * @stable ICU 4.0
605     */
606    const DateIntervalInfo* getDateIntervalInfo(void) const;
607
608
609    /**
610     * Set the date time interval patterns.
611     * @param newIntervalPatterns   the given interval patterns to copy.
612     * @param status          output param set to success/failure code on exit
613     * @stable ICU 4.0
614     */
615    void setDateIntervalInfo(const DateIntervalInfo& newIntervalPatterns,
616                             UErrorCode& status);
617
618
619    /**
620     * Gets the date formatter. The DateIntervalFormat instance continues to own
621     * the returned DateFormatter object, and will use and possibly modify it
622     * during format operations. In a multi-threaded environment, the returned
623     * DateFormat can only be used if it is certain that no other threads are
624     * concurrently using this DateIntervalFormatter, even for nominally const
625     * functions.
626     *
627     * @return the date formatter associated with this date interval formatter.
628     * @stable ICU 4.0
629     */
630    const DateFormat* getDateFormat(void) const;
631
632    /**
633     * Returns a reference to the TimeZone used by this DateIntervalFormat's calendar.
634     * @return the time zone associated with the calendar of DateIntervalFormat.
635     * @stable ICU 4.8
636     */
637    virtual const TimeZone& getTimeZone(void) const;
638
639    /**
640     * Sets the time zone for the calendar used by this DateIntervalFormat object. The
641     * caller no longer owns the TimeZone object and should not delete it after this call.
642     * @param zoneToAdopt the TimeZone to be adopted.
643     * @stable ICU 4.8
644     */
645    virtual void adoptTimeZone(TimeZone* zoneToAdopt);
646
647    /**
648     * Sets the time zone for the calendar used by this DateIntervalFormat object.
649     * @param zone the new time zone.
650     * @stable ICU 4.8
651     */
652    virtual void setTimeZone(const TimeZone& zone);
653
654    /**
655     * Return the class ID for this class. This is useful only for comparing to
656     * a return value from getDynamicClassID(). For example:
657     * <pre>
658     * .   Base* polymorphic_pointer = createPolymorphicObject();
659     * .   if (polymorphic_pointer->getDynamicClassID() ==
660     * .       erived::getStaticClassID()) ...
661     * </pre>
662     * @return          The class ID for all objects of this class.
663     * @stable ICU 4.0
664     */
665    static UClassID U_EXPORT2 getStaticClassID(void);
666
667    /**
668     * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
669     * method is to implement a simple version of RTTI, since not all C++
670     * compilers support genuine RTTI. Polymorphic operator==() and clone()
671     * methods call this method.
672     *
673     * @return          The class ID for this object. All objects of a
674     *                  given class have the same class ID.  Objects of
675     *                  other classes have different class IDs.
676     * @stable ICU 4.0
677     */
678    virtual UClassID getDynamicClassID(void) const;
679
680protected:
681
682    /**
683     * Copy constructor.
684     * @stable ICU 4.0
685     */
686    DateIntervalFormat(const DateIntervalFormat&);
687
688    /**
689     * Assignment operator.
690     * @stable ICU 4.0
691     */
692    DateIntervalFormat& operator=(const DateIntervalFormat&);
693
694private:
695
696    /*
697     * This is for ICU internal use only. Please do not use.
698     * Save the interval pattern information.
699     * Interval pattern consists of 2 single date patterns and the separator.
700     * For example, interval pattern "MMM d - MMM d, yyyy" consists
701     * a single date pattern "MMM d", another single date pattern "MMM d, yyyy",
702     * and a separator "-".
703     * The pattern is divided into 2 parts. For above example,
704     * the first part is "MMM d - ", and the second part is "MMM d, yyyy".
705     * Also, the first date appears in an interval pattern could be
706     * the earlier date or the later date.
707     * And such information is saved in the interval pattern as well.
708     */
709    struct PatternInfo {
710        UnicodeString firstPart;
711        UnicodeString secondPart;
712        /**
713         * Whether the first date in interval pattern is later date or not.
714         * Fallback format set the default ordering.
715         * And for a particular interval pattern, the order can be
716         * overriden by prefixing the interval pattern with "latestFirst:" or
717         * "earliestFirst:"
718         * For example, given 2 date, Jan 10, 2007 to Feb 10, 2007.
719         * if the fallback format is "{0} - {1}",
720         * and the pattern is "d MMM - d MMM yyyy", the interval format is
721         * "10 Jan - 10 Feb, 2007".
722         * If the pattern is "latestFirst:d MMM - d MMM yyyy",
723         * the interval format is "10 Feb - 10 Jan, 2007"
724         */
725        UBool         laterDateFirst;
726    };
727
728
729    /**
730     * default constructor
731     * @internal (private)
732     */
733    DateIntervalFormat();
734
735    /**
736     * Construct a DateIntervalFormat from DateFormat,
737     * a DateIntervalInfo, and skeleton.
738     * DateFormat provides the timezone, calendar,
739     * full pattern, and date format symbols information.
740     * It should be a SimpleDateFormat object which
741     * has a pattern in it.
742     * the DateIntervalInfo provides the interval patterns.
743     *
744     * Note: the DateIntervalFormat takes ownership of both
745     * DateFormat and DateIntervalInfo objects.
746     * Caller should not delete them.
747     *
748     * @param locale    the locale of this date interval formatter.
749     * @param dtItvInfo the DateIntervalInfo object to be adopted.
750     * @param skeleton  the skeleton of the date formatter
751     * @param status    output param set to success/failure code on exit
752     */
753    DateIntervalFormat(const Locale& locale, DateIntervalInfo* dtItvInfo,
754                       const UnicodeString* skeleton, UErrorCode& status);
755
756
757    /**
758     * Construct a DateIntervalFormat from DateFormat
759     * and a DateIntervalInfo.
760     *
761     * It is a wrapper of the constructor.
762     *
763     * @param locale    the locale of this date interval formatter.
764     * @param dtitvinf  the DateIntervalInfo object to be adopted.
765     * @param skeleton  the skeleton of this formatter.
766     * @param status    Output param set to success/failure code.
767     * @return          a date time interval formatter which the caller owns.
768     */
769    static DateIntervalFormat* U_EXPORT2 create(const Locale& locale,
770                                                DateIntervalInfo* dtitvinf,
771                                                const UnicodeString* skeleton,
772                                                UErrorCode& status);
773
774    /**
775     *  Below are for generating interval patterns local to the formatter
776     */
777
778    /** Like fallbackFormat, but only formats the range part of the fallback. */
779    void fallbackFormatRange(
780        Calendar& fromCalendar,
781        Calendar& toCalendar,
782        UnicodeString& appendTo,
783        int8_t& firstIndex,
784        FieldPositionHandler& fphandler,
785        UErrorCode& status) const;
786
787    /**
788     * Format 2 Calendars using fall-back interval pattern
789     *
790     * The full pattern used in this fall-back format is the
791     * full pattern of the date formatter.
792     *
793     * gFormatterMutex must already be locked when calling this function.
794     *
795     * @param fromCalendar      calendar set to the from date in date interval
796     *                          to be formatted into date interval string
797     * @param toCalendar        calendar set to the to date in date interval
798     *                          to be formatted into date interval string
799     * @param fromToOnSameDay   TRUE iff from and to dates are on the same day
800     *                          (any difference is in ampm/hours or below)
801     * @param appendTo          Output parameter to receive result.
802     *                          Result is appended to existing contents.
803     * @param firstIndex        See formatImpl for more information.
804     * @param fphandler         See formatImpl for more information.
805     * @param status            output param set to success/failure code on exit
806     * @return                  Reference to 'appendTo' parameter.
807     * @internal (private)
808     */
809    UnicodeString& fallbackFormat(Calendar& fromCalendar,
810                                  Calendar& toCalendar,
811                                  UBool fromToOnSameDay,
812                                  UnicodeString& appendTo,
813                                  int8_t& firstIndex,
814                                  FieldPositionHandler& fphandler,
815                                  UErrorCode& status) const;
816
817
818
819    /**
820     * Initialize interval patterns locale to this formatter
821     *
822     * This code is a bit complicated since
823     * 1. the interval patterns saved in resource bundle files are interval
824     *    patterns based on date or time only.
825     *    It does not have interval patterns based on both date and time.
826     *    Interval patterns on both date and time are algorithm generated.
827     *
828     *    For example, it has interval patterns on skeleton "dMy" and "hm",
829     *    but it does not have interval patterns on skeleton "dMyhm".
830     *
831     *    The rule to generate interval patterns for both date and time skeleton are
832     *    1) when the year, month, or day differs, concatenate the two original
833     *    expressions with a separator between,
834     *    For example, interval pattern from "Jan 10, 2007 10:10 am"
835     *    to "Jan 11, 2007 10:10am" is
836     *    "Jan 10, 2007 10:10 am - Jan 11, 2007 10:10am"
837     *
838     *    2) otherwise, present the date followed by the range expression
839     *    for the time.
840     *    For example, interval pattern from "Jan 10, 2007 10:10 am"
841     *    to "Jan 10, 2007 11:10am" is
842     *    "Jan 10, 2007 10:10 am - 11:10am"
843     *
844     * 2. even a pattern does not request a certain calendar field,
845     *    the interval pattern needs to include such field if such fields are
846     *    different between 2 dates.
847     *    For example, a pattern/skeleton is "hm", but the interval pattern
848     *    includes year, month, and date when year, month, and date differs.
849     *
850     *
851     * @param status    output param set to success/failure code on exit
852     */
853    void initializePattern(UErrorCode& status);
854
855
856
857    /**
858     * Set fall back interval pattern given a calendar field,
859     * a skeleton, and a date time pattern generator.
860     * @param field      the largest different calendar field
861     * @param skeleton   a skeleton
862     * @param status     output param set to success/failure code on exit
863     */
864    void setFallbackPattern(UCalendarDateFields field,
865                            const UnicodeString& skeleton,
866                            UErrorCode& status);
867
868
869
870    /**
871     * get separated date and time skeleton from a combined skeleton.
872     *
873     * The difference between date skeleton and normalizedDateSkeleton are:
874     * 1. both 'y' and 'd' are appeared only once in normalizeDateSkeleton
875     * 2. 'E' and 'EE' are normalized into 'EEE'
876     * 3. 'MM' is normalized into 'M'
877     *
878     ** the difference between time skeleton and normalizedTimeSkeleton are:
879     * 1. both 'H' and 'h' are normalized as 'h' in normalized time skeleton,
880     * 2. 'a' is omitted in normalized time skeleton.
881     * 3. there is only one appearance for 'h', 'm','v', 'z' in normalized time
882     *    skeleton
883     *
884     *
885     *  @param skeleton               given combined skeleton.
886     *  @param date                   Output parameter for date only skeleton.
887     *  @param normalizedDate         Output parameter for normalized date only
888     *
889     *  @param time                   Output parameter for time only skeleton.
890     *  @param normalizedTime         Output parameter for normalized time only
891     *                                skeleton.
892     *
893     */
894    static void  U_EXPORT2 getDateTimeSkeleton(const UnicodeString& skeleton,
895                                    UnicodeString& date,
896                                    UnicodeString& normalizedDate,
897                                    UnicodeString& time,
898                                    UnicodeString& normalizedTime);
899
900
901
902    /**
903     * Generate date or time interval pattern from resource,
904     * and set them into the interval pattern locale to this formatter.
905     *
906     * It needs to handle the following:
907     * 1. need to adjust field width.
908     *    For example, the interval patterns saved in DateIntervalInfo
909     *    includes "dMMMy", but not "dMMMMy".
910     *    Need to get interval patterns for dMMMMy from dMMMy.
911     *    Another example, the interval patterns saved in DateIntervalInfo
912     *    includes "hmv", but not "hmz".
913     *    Need to get interval patterns for "hmz' from 'hmv'
914     *
915     * 2. there might be no pattern for 'y' differ for skeleton "Md",
916     *    in order to get interval patterns for 'y' differ,
917     *    need to look for it from skeleton 'yMd'
918     *
919     * @param dateSkeleton   normalized date skeleton
920     * @param timeSkeleton   normalized time skeleton
921     * @return               whether the resource is found for the skeleton.
922     *                       TRUE if interval pattern found for the skeleton,
923     *                       FALSE otherwise.
924     */
925    UBool setSeparateDateTimePtn(const UnicodeString& dateSkeleton,
926                                 const UnicodeString& timeSkeleton);
927
928
929
930
931    /**
932     * Generate interval pattern from existing resource
933     *
934     * It not only save the interval patterns,
935     * but also return the extended skeleton and its best match skeleton.
936     *
937     * @param field           largest different calendar field
938     * @param skeleton        skeleton
939     * @param bestSkeleton    the best match skeleton which has interval pattern
940     *                        defined in resource
941     * @param differenceInfo  the difference between skeleton and best skeleton
942     *         0 means the best matched skeleton is the same as input skeleton
943     *         1 means the fields are the same, but field width are different
944     *         2 means the only difference between fields are v/z,
945     *        -1 means there are other fields difference
946     *
947     * @param extendedSkeleton      extended skeleton
948     * @param extendedBestSkeleton  extended best match skeleton
949     * @return                      whether the interval pattern is found
950     *                              through extending skeleton or not.
951     *                              TRUE if interval pattern is found by
952     *                              extending skeleton, FALSE otherwise.
953     */
954    UBool setIntervalPattern(UCalendarDateFields field,
955                             const UnicodeString* skeleton,
956                             const UnicodeString* bestSkeleton,
957                             int8_t differenceInfo,
958                             UnicodeString* extendedSkeleton = NULL,
959                             UnicodeString* extendedBestSkeleton = NULL);
960
961    /**
962     * Adjust field width in best match interval pattern to match
963     * the field width in input skeleton.
964     *
965     * TODO (xji) make a general solution
966     * The adjusting rule can be:
967     * 1. always adjust
968     * 2. never adjust
969     * 3. default adjust, which means adjust according to the following rules
970     * 3.1 always adjust string, such as MMM and MMMM
971     * 3.2 never adjust between string and numeric, such as MM and MMM
972     * 3.3 always adjust year
973     * 3.4 do not adjust 'd', 'h', or 'm' if h presents
974     * 3.5 do not adjust 'M' if it is numeric(?)
975     *
976     * Since date interval format is well-formed format,
977     * date and time skeletons are normalized previously,
978     * till this stage, the adjust here is only "adjust strings, such as MMM
979     * and MMMM, EEE and EEEE.
980     *
981     * @param inputSkeleton            the input skeleton
982     * @param bestMatchSkeleton        the best match skeleton
983     * @param bestMatchIntervalPattern the best match interval pattern
984     * @param differenceInfo           the difference between 2 skeletons
985     *                                 1 means only field width differs
986     *                                 2 means v/z exchange
987     * @param adjustedIntervalPattern  adjusted interval pattern
988     */
989    static void U_EXPORT2 adjustFieldWidth(
990                            const UnicodeString& inputSkeleton,
991                            const UnicodeString& bestMatchSkeleton,
992                            const UnicodeString& bestMatchIntervalPattern,
993                            int8_t differenceInfo,
994                            UnicodeString& adjustedIntervalPattern);
995
996    /**
997     * Concat a single date pattern with a time interval pattern,
998     * set it into the intervalPatterns, while field is time field.
999     * This is used to handle time interval patterns on skeleton with
1000     * both time and date. Present the date followed by
1001     * the range expression for the time.
1002     * @param format         date and time format
1003     * @param datePattern    date pattern
1004     * @param field          time calendar field: AM_PM, HOUR, MINUTE
1005     * @param status         output param set to success/failure code on exit
1006     */
1007    void concatSingleDate2TimeInterval(UnicodeString& format,
1008                                       const UnicodeString& datePattern,
1009                                       UCalendarDateFields field,
1010                                       UErrorCode& status);
1011
1012    /**
1013     * check whether a calendar field present in a skeleton.
1014     * @param field      calendar field need to check
1015     * @param skeleton   given skeleton on which to check the calendar field
1016     * @return           true if field present in a skeleton.
1017     */
1018    static UBool U_EXPORT2 fieldExistsInSkeleton(UCalendarDateFields field,
1019                                                 const UnicodeString& skeleton);
1020
1021
1022    /**
1023     * Split interval patterns into 2 part.
1024     * @param intervalPattern  interval pattern
1025     * @return the index in interval pattern which split the pattern into 2 part
1026     */
1027    static int32_t  U_EXPORT2 splitPatternInto2Part(const UnicodeString& intervalPattern);
1028
1029
1030    /**
1031     * Break interval patterns as 2 part and save them into pattern info.
1032     * @param field            calendar field
1033     * @param intervalPattern  interval pattern
1034     */
1035    void setIntervalPattern(UCalendarDateFields field,
1036                            const UnicodeString& intervalPattern);
1037
1038
1039    /**
1040     * Break interval patterns as 2 part and save them into pattern info.
1041     * @param field            calendar field
1042     * @param intervalPattern  interval pattern
1043     * @param laterDateFirst   whether later date appear first in interval pattern
1044     */
1045    void setIntervalPattern(UCalendarDateFields field,
1046                            const UnicodeString& intervalPattern,
1047                            UBool laterDateFirst);
1048
1049
1050    /**
1051     * Set pattern information.
1052     *
1053     * @param field            calendar field
1054     * @param firstPart        the first part in interval pattern
1055     * @param secondPart       the second part in interval pattern
1056     * @param laterDateFirst   whether the first date in intervalPattern
1057     *                         is earlier date or later date
1058     */
1059    void setPatternInfo(UCalendarDateFields field,
1060                        const UnicodeString* firstPart,
1061                        const UnicodeString* secondPart,
1062                        UBool laterDateFirst);
1063
1064    /**
1065     * Format 2 Calendars to produce a string.
1066     * Implementation of the similar public format function.
1067     * Must be called with gFormatterMutex already locked.
1068     *
1069     * Note: "fromCalendar" and "toCalendar" are not const,
1070     * since calendar is not const in  SimpleDateFormat::format(Calendar&),
1071     *
1072     * @param fromCalendar      calendar set to the from date in date interval
1073     *                          to be formatted into date interval string
1074     * @param toCalendar        calendar set to the to date in date interval
1075     *                          to be formatted into date interval string
1076     * @param appendTo          Output parameter to receive result.
1077     *                          Result is appended to existing contents.
1078     * @param firstIndex        0 if the first output date is fromCalendar;
1079     *                          1 if it corresponds to toCalendar;
1080     *                          -1 if there is only one date printed.
1081     * @param fphandler         Handler for field position information.
1082     *                          The fields will be from the UDateFormatField enum.
1083     * @param status            Output param filled with success/failure status.
1084     *                          Caller needs to make sure it is SUCCESS
1085     *                          at the function entrance
1086     * @return                  Reference to 'appendTo' parameter.
1087     * @internal (private)
1088     */
1089    UnicodeString& formatImpl(Calendar& fromCalendar,
1090                              Calendar& toCalendar,
1091                              UnicodeString& appendTo,
1092                              int8_t& firstIndex,
1093                              FieldPositionHandler& fphandler,
1094                              UErrorCode& status) const ;
1095
1096    /** Version of formatImpl for DateInterval. */
1097    UnicodeString& formatIntervalImpl(const DateInterval& dtInterval,
1098                              UnicodeString& appendTo,
1099                              int8_t& firstIndex,
1100                              FieldPositionHandler& fphandler,
1101                              UErrorCode& status) const;
1102
1103
1104    // from calendar field to pattern letter
1105    static const char16_t fgCalendarFieldToPatternLetter[];
1106
1107
1108    /**
1109     * The interval patterns for this locale.
1110     */
1111    DateIntervalInfo*     fInfo;
1112
1113    /**
1114     * The DateFormat object used to format single pattern
1115     */
1116    SimpleDateFormat*     fDateFormat;
1117
1118    /**
1119     * The 2 calendars with the from and to date.
1120     * could re-use the calendar in fDateFormat,
1121     * but keeping 2 calendars make it clear and clean.
1122     */
1123    Calendar* fFromCalendar;
1124    Calendar* fToCalendar;
1125
1126    Locale fLocale;
1127
1128    /**
1129     * Following are interval information relevant (locale) to this formatter.
1130     */
1131    UnicodeString fSkeleton;
1132    PatternInfo fIntervalPatterns[DateIntervalInfo::kIPI_MAX_INDEX];
1133
1134    /**
1135     * Patterns for fallback formatting.
1136     */
1137    UnicodeString* fDatePattern;
1138    UnicodeString* fTimePattern;
1139    UnicodeString* fDateTimeFormat;
1140};
1141
1142inline UBool
1143DateIntervalFormat::operator!=(const Format& other) const  {
1144    return !operator==(other);
1145}
1146
1147U_NAMESPACE_END
1148
1149#endif /* #if !UCONFIG_NO_FORMATTING */
1150
1151#endif /* U_SHOW_CPLUSPLUS_API */
1152
1153#endif // _DTITVFMT_H__
1154//eof
1155 
codekingpro/portable-devtools · Team Ai