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