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