• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 2007-2016, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 *******************************************************************************
8 *
9 * File DTPTNGEN.H
10 *
11 *******************************************************************************
12 */
13 
14 #ifndef __DTPTNGEN_H__
15 #define __DTPTNGEN_H__
16 
17 #include "unicode/datefmt.h"
18 #include "unicode/locid.h"
19 #include "unicode/udat.h"
20 #include "unicode/udatpg.h"
21 
22 U_NAMESPACE_BEGIN
23 
24 /**
25  * \file
26  * \brief C++ API: Date/Time Pattern Generator
27  */
28 
29 
30 class Hashtable;
31 class FormatParser;
32 class DateTimeMatcher;
33 class DistanceInfo;
34 class PatternMap;
35 class PtnSkeleton;
36 class SharedDateTimePatternGenerator;
37 
38 /**
39  * This class provides flexible generation of date format patterns, like "yy-MM-dd".
40  * The user can build up the generator by adding successive patterns. Once that
41  * is done, a query can be made using a "skeleton", which is a pattern which just
42  * includes the desired fields and lengths. The generator will return the "best fit"
43  * pattern corresponding to that skeleton.
44  * <p>The main method people will use is getBestPattern(String skeleton),
45  * since normally this class is pre-built with data from a particular locale.
46  * However, generators can be built directly from other data as well.
47  * <p><i>Issue: may be useful to also have a function that returns the list of
48  * fields in a pattern, in order, since we have that internally.
49  * That would be useful for getting the UI order of field elements.</i>
50  * @stable ICU 3.8
51 **/
52 class U_I18N_API DateTimePatternGenerator : public UObject {
53 public:
54     /**
55      * Construct a flexible generator according to default locale.
56      * @param status  Output param set to success/failure code on exit,
57      *               which must not indicate a failure before the function call.
58      * @stable ICU 3.8
59      */
60     static DateTimePatternGenerator* U_EXPORT2 createInstance(UErrorCode& status);
61 
62     /**
63      * Construct a flexible generator according to data for a given locale.
64      * @param uLocale
65      * @param status  Output param set to success/failure code on exit,
66      *               which must not indicate a failure before the function call.
67      * @stable ICU 3.8
68      */
69     static DateTimePatternGenerator* U_EXPORT2 createInstance(const Locale& uLocale, UErrorCode& status);
70 
71 #ifndef U_HIDE_INTERNAL_API
72 
73     /**
74      * For ICU use only
75      *
76      * @internal
77      */
78     static DateTimePatternGenerator* U_EXPORT2 internalMakeInstance(const Locale& uLocale, UErrorCode& status);
79 
80 #endif /* U_HIDE_INTERNAL_API */
81 
82     /**
83      * Create an empty generator, to be constructed with addPattern(...) etc.
84      * @param status  Output param set to success/failure code on exit,
85      *               which must not indicate a failure before the function call.
86      * @stable ICU 3.8
87      */
88      static DateTimePatternGenerator* U_EXPORT2 createEmptyInstance(UErrorCode& status);
89 
90     /**
91      * Destructor.
92      * @stable ICU 3.8
93      */
94     virtual ~DateTimePatternGenerator();
95 
96     /**
97      * Clone DateTimePatternGenerator object. Clients are responsible for
98      * deleting the DateTimePatternGenerator object cloned.
99      * @stable ICU 3.8
100      */
101     DateTimePatternGenerator* clone() const;
102 
103      /**
104       * Return true if another object is semantically equal to this one.
105       *
106       * @param other    the DateTimePatternGenerator object to be compared with.
107       * @return         true if other is semantically equal to this.
108       * @stable ICU 3.8
109       */
110     UBool operator==(const DateTimePatternGenerator& other) const;
111 
112     /**
113      * Return true if another object is semantically unequal to this one.
114      *
115      * @param other    the DateTimePatternGenerator object to be compared with.
116      * @return         true if other is semantically unequal to this.
117      * @stable ICU 3.8
118      */
119     UBool operator!=(const DateTimePatternGenerator& other) const;
120 
121     /**
122      * Utility to return a unique skeleton from a given pattern. For example,
123      * both "MMM-dd" and "dd/MMM" produce the skeleton "MMMdd".
124      *
125      * @param pattern   Input pattern, such as "dd/MMM"
126      * @param status  Output param set to success/failure code on exit,
127      *                  which must not indicate a failure before the function call.
128      * @return skeleton such as "MMMdd"
129      * @stable ICU 56
130      */
131     static UnicodeString staticGetSkeleton(const UnicodeString& pattern, UErrorCode& status);
132 
133     /**
134      * Utility to return a unique skeleton from a given pattern. For example,
135      * both "MMM-dd" and "dd/MMM" produce the skeleton "MMMdd".
136      * getSkeleton() works exactly like staticGetSkeleton().
137      * Use staticGetSkeleton() instead of getSkeleton().
138      *
139      * @param pattern   Input pattern, such as "dd/MMM"
140      * @param status  Output param set to success/failure code on exit,
141      *                  which must not indicate a failure before the function call.
142      * @return skeleton such as "MMMdd"
143      * @stable ICU 3.8
144      */
145     UnicodeString getSkeleton(const UnicodeString& pattern, UErrorCode& status); /* {
146         The function is commented out because it is a stable API calling a draft API.
147         After staticGetSkeleton becomes stable, staticGetSkeleton can be used and
148         these comments and the definition of getSkeleton in dtptngen.cpp should be removed.
149         return staticGetSkeleton(pattern, status);
150     }*/
151 
152     /**
153      * Utility to return a unique base skeleton from a given pattern. This is
154      * the same as the skeleton, except that differences in length are minimized
155      * so as to only preserve the difference between string and numeric form. So
156      * for example, both "MMM-dd" and "d/MMM" produce the skeleton "MMMd"
157      * (notice the single d).
158      *
159      * @param pattern  Input pattern, such as "dd/MMM"
160      * @param status  Output param set to success/failure code on exit,
161      *               which must not indicate a failure before the function call.
162      * @return base skeleton, such as "MMMd"
163      * @stable ICU 56
164      */
165     static UnicodeString staticGetBaseSkeleton(const UnicodeString& pattern, UErrorCode& status);
166 
167     /**
168      * Utility to return a unique base skeleton from a given pattern. This is
169      * the same as the skeleton, except that differences in length are minimized
170      * so as to only preserve the difference between string and numeric form. So
171      * for example, both "MMM-dd" and "d/MMM" produce the skeleton "MMMd"
172      * (notice the single d).
173      * getBaseSkeleton() works exactly like staticGetBaseSkeleton().
174      * Use staticGetBaseSkeleton() instead of getBaseSkeleton().
175      *
176      * @param pattern  Input pattern, such as "dd/MMM"
177      * @param status  Output param set to success/failure code on exit,
178      *               which must not indicate a failure before the function call.
179      * @return base skeleton, such as "MMMd"
180      * @stable ICU 3.8
181      */
182     UnicodeString getBaseSkeleton(const UnicodeString& pattern, UErrorCode& status); /* {
183         The function is commented out because it is a stable API calling a draft API.
184         After staticGetBaseSkeleton becomes stable, staticGetBaseSkeleton can be used and
185         these comments and the definition of getBaseSkeleton in dtptngen.cpp should be removed.
186         return staticGetBaseSkeleton(pattern, status);
187     }*/
188 
189     /**
190      * Adds a pattern to the generator. If the pattern has the same skeleton as
191      * an existing pattern, and the override parameter is set, then the previous
192      * value is overriden. Otherwise, the previous value is retained. In either
193      * case, the conflicting status is set and previous vale is stored in
194      * conflicting pattern.
195      * <p>
196      * Note that single-field patterns (like "MMM") are automatically added, and
197      * don't need to be added explicitly!
198      *
199      * @param pattern   Input pattern, such as "dd/MMM"
200      * @param override  When existing values are to be overridden use true,
201      *                   otherwise use false.
202      * @param conflictingPattern  Previous pattern with the same skeleton.
203      * @param status  Output param set to success/failure code on exit,
204      *               which must not indicate a failure before the function call.
205      * @return conflicting status.  The value could be UDATPG_NO_CONFLICT,
206      *                             UDATPG_BASE_CONFLICT or UDATPG_CONFLICT.
207      * @stable ICU 3.8
208 	 * <p>
209 	 * <h4>Sample code</h4>
210 	 * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1
211 	 * \snippet samples/dtptngsample/dtptngsample.cpp addPatternExample
212 	 * <p>
213      */
214     UDateTimePatternConflict addPattern(const UnicodeString& pattern,
215                                         UBool override,
216                                         UnicodeString& conflictingPattern,
217                                         UErrorCode& status);
218 
219     /**
220      * An AppendItem format is a pattern used to append a field if there is no
221      * good match. For example, suppose that the input skeleton is "GyyyyMMMd",
222      * and there is no matching pattern internally, but there is a pattern
223      * matching "yyyyMMMd", say "d-MM-yyyy". Then that pattern is used, plus the
224      * G. The way these two are conjoined is by using the AppendItemFormat for G
225      * (era). So if that value is, say "{0}, {1}" then the final resulting
226      * pattern is "d-MM-yyyy, G".
227      * <p>
228      * There are actually three available variables: {0} is the pattern so far,
229      * {1} is the element we are adding, and {2} is the name of the element.
230      * <p>
231      * This reflects the way that the CLDR data is organized.
232      *
233      * @param field  such as UDATPG_ERA_FIELD.
234      * @param value  pattern, such as "{0}, {1}"
235      * @stable ICU 3.8
236      */
237     void setAppendItemFormat(UDateTimePatternField field, const UnicodeString& value);
238 
239     /**
240      * Getter corresponding to setAppendItemFormat. Values below 0 or at or
241      * above UDATPG_FIELD_COUNT are illegal arguments.
242      *
243      * @param  field  such as UDATPG_ERA_FIELD.
244      * @return append pattern for field
245      * @stable ICU 3.8
246      */
247     const UnicodeString& getAppendItemFormat(UDateTimePatternField field) const;
248 
249     /**
250      * Sets the names of field, eg "era" in English for ERA. These are only
251      * used if the corresponding AppendItemFormat is used, and if it contains a
252      * {2} variable.
253      * <p>
254      * This reflects the way that the CLDR data is organized.
255      *
256      * @param field   such as UDATPG_ERA_FIELD.
257      * @param value   name of the field
258      * @stable ICU 3.8
259      */
260     void setAppendItemName(UDateTimePatternField field, const UnicodeString& value);
261 
262     /**
263      * Getter corresponding to setAppendItemNames. Values below 0 or at or above
264      * UDATPG_FIELD_COUNT are illegal arguments.
265      *
266      * @param field  such as UDATPG_ERA_FIELD.
267      * @return name for field
268      * @stable ICU 3.8
269      */
270     const UnicodeString& getAppendItemName(UDateTimePatternField field) const;
271 
272     /**
273      * The DateTimeFormat is a message format pattern used to compose date and
274      * time patterns. The default pattern in the root locale is "{1} {0}", where
275      * {1} will be replaced by the date pattern and {0} will be replaced by the
276      * time pattern; however, other locales may specify patterns such as
277      * "{1}, {0}" or "{1} 'at' {0}", etc.
278      * <p>
279      * This is used when the input skeleton contains both date and time fields,
280      * but there is not a close match among the added patterns. For example,
281      * suppose that this object was created by adding "dd-MMM" and "hh:mm", and
282      * its datetimeFormat is the default "{1} {0}". Then if the input skeleton
283      * is "MMMdhmm", there is not an exact match, so the input skeleton is
284      * broken up into two components "MMMd" and "hmm". There are close matches
285      * for those two skeletons, so the result is put together with this pattern,
286      * resulting in "d-MMM h:mm".
287      *
288      * @param dateTimeFormat
289      *            message format pattern, here {1} will be replaced by the date
290      *            pattern and {0} will be replaced by the time pattern.
291      * @stable ICU 3.8
292      */
293     void setDateTimeFormat(const UnicodeString& dateTimeFormat);
294 
295     /**
296      * Getter corresponding to setDateTimeFormat.
297      * @return DateTimeFormat.
298      * @stable ICU 3.8
299      */
300     const UnicodeString& getDateTimeFormat() const;
301 
302     /**
303      * Return the best pattern matching the input skeleton. It is guaranteed to
304      * have all of the fields in the skeleton.
305      *
306      * @param skeleton
307      *            The skeleton is a pattern containing only the variable fields.
308      *            For example, "MMMdd" and "mmhh" are skeletons.
309      * @param status  Output param set to success/failure code on exit,
310      *               which must not indicate a failure before the function call.
311      * @return bestPattern
312      *            The best pattern found from the given skeleton.
313      * @stable ICU 3.8
314 	 * <p>
315 	 * <h4>Sample code</h4>
316 	 * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1
317 	 * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample
318 	 * <p>
319      */
320      UnicodeString getBestPattern(const UnicodeString& skeleton, UErrorCode& status);
321 
322 
323     /**
324      * Return the best pattern matching the input skeleton. It is guaranteed to
325      * have all of the fields in the skeleton.
326      *
327      * @param skeleton
328      *            The skeleton is a pattern containing only the variable fields.
329      *            For example, "MMMdd" and "mmhh" are skeletons.
330      * @param options
331      *            Options for forcing the length of specified fields in the
332      *            returned pattern to match those in the skeleton (when this
333      *            would not happen otherwise). For default behavior, use
334      *            UDATPG_MATCH_NO_OPTIONS.
335      * @param status
336      *            Output param set to success/failure code on exit,
337      *            which must not indicate a failure before the function call.
338      * @return bestPattern
339      *            The best pattern found from the given skeleton.
340      * @stable ICU 4.4
341      */
342      UnicodeString getBestPattern(const UnicodeString& skeleton,
343                                   UDateTimePatternMatchOptions options,
344                                   UErrorCode& status);
345 
346 
347     /**
348      * Adjusts the field types (width and subtype) of a pattern to match what is
349      * in a skeleton. That is, if you supply a pattern like "d-M H:m", and a
350      * skeleton of "MMMMddhhmm", then the input pattern is adjusted to be
351      * "dd-MMMM hh:mm". This is used internally to get the best match for the
352      * input skeleton, but can also be used externally.
353      *
354      * @param pattern Input pattern
355      * @param skeleton
356      *            The skeleton is a pattern containing only the variable fields.
357      *            For example, "MMMdd" and "mmhh" are skeletons.
358      * @param status  Output param set to success/failure code on exit,
359      *               which must not indicate a failure before the function call.
360      * @return pattern adjusted to match the skeleton fields widths and subtypes.
361      * @stable ICU 3.8
362 	 * <p>
363 	 * <h4>Sample code</h4>
364 	 * \snippet samples/dtptngsample/dtptngsample.cpp getBestPatternExample1
365 	 * \snippet samples/dtptngsample/dtptngsample.cpp replaceFieldTypesExample
366 	 * <p>
367      */
368      UnicodeString replaceFieldTypes(const UnicodeString& pattern,
369                                      const UnicodeString& skeleton,
370                                      UErrorCode& status);
371 
372     /**
373      * Adjusts the field types (width and subtype) of a pattern to match what is
374      * in a skeleton. That is, if you supply a pattern like "d-M H:m", and a
375      * skeleton of "MMMMddhhmm", then the input pattern is adjusted to be
376      * "dd-MMMM hh:mm". This is used internally to get the best match for the
377      * input skeleton, but can also be used externally.
378      *
379      * @param pattern Input pattern
380      * @param skeleton
381      *            The skeleton is a pattern containing only the variable fields.
382      *            For example, "MMMdd" and "mmhh" are skeletons.
383      * @param options
384      *            Options controlling whether the length of specified fields in the
385      *            pattern are adjusted to match those in the skeleton (when this
386      *            would not happen otherwise). For default behavior, use
387      *            UDATPG_MATCH_NO_OPTIONS.
388      * @param status
389      *            Output param set to success/failure code on exit,
390      *            which must not indicate a failure before the function call.
391      * @return pattern adjusted to match the skeleton fields widths and subtypes.
392      * @stable ICU 4.4
393      */
394      UnicodeString replaceFieldTypes(const UnicodeString& pattern,
395                                      const UnicodeString& skeleton,
396                                      UDateTimePatternMatchOptions options,
397                                      UErrorCode& status);
398 
399     /**
400      * Return a list of all the skeletons (in canonical form) from this class.
401      *
402      * Call getPatternForSkeleton() to get the corresponding pattern.
403      *
404      * @param status  Output param set to success/failure code on exit,
405      *               which must not indicate a failure before the function call.
406      * @return StringEnumeration with the skeletons.
407      *         The caller must delete the object.
408      * @stable ICU 3.8
409      */
410      StringEnumeration* getSkeletons(UErrorCode& status) const;
411 
412      /**
413       * Get the pattern corresponding to a given skeleton.
414       * @param skeleton
415       * @return pattern corresponding to a given skeleton.
416       * @stable ICU 3.8
417       */
418      const UnicodeString& getPatternForSkeleton(const UnicodeString& skeleton) const;
419 
420     /**
421      * Return a list of all the base skeletons (in canonical form) from this class.
422      *
423      * @param status  Output param set to success/failure code on exit,
424      *               which must not indicate a failure before the function call.
425      * @return a StringEnumeration with the base skeletons.
426      *         The caller must delete the object.
427      * @stable ICU 3.8
428      */
429      StringEnumeration* getBaseSkeletons(UErrorCode& status) const;
430 
431 #ifndef U_HIDE_INTERNAL_API
432      /**
433       * Return a list of redundant patterns are those which if removed, make no
434       * difference in the resulting getBestPattern values. This method returns a
435       * list of them, to help check the consistency of the patterns used to build
436       * this generator.
437       *
438       * @param status  Output param set to success/failure code on exit,
439       *               which must not indicate a failure before the function call.
440       * @return a StringEnumeration with the redundant pattern.
441       *         The caller must delete the object.
442       * @internal ICU 3.8
443       */
444      StringEnumeration* getRedundants(UErrorCode& status);
445 #endif  /* U_HIDE_INTERNAL_API */
446 
447     /**
448      * The decimal value is used in formatting fractions of seconds. If the
449      * skeleton contains fractional seconds, then this is used with the
450      * fractional seconds. For example, suppose that the input pattern is
451      * "hhmmssSSSS", and the best matching pattern internally is "H:mm:ss", and
452      * the decimal string is ",". Then the resulting pattern is modified to be
453      * "H:mm:ss,SSSS"
454      *
455      * @param decimal
456      * @stable ICU 3.8
457      */
458     void setDecimal(const UnicodeString& decimal);
459 
460     /**
461      * Getter corresponding to setDecimal.
462      * @return UnicodeString corresponding to the decimal point
463      * @stable ICU 3.8
464      */
465     const UnicodeString& getDecimal() const;
466 
467     /**
468      * ICU "poor man's RTTI", returns a UClassID for the actual class.
469      *
470      * @stable ICU 3.8
471      */
472     virtual UClassID getDynamicClassID() const;
473 
474     /**
475      * ICU "poor man's RTTI", returns a UClassID for this class.
476      *
477      * @stable ICU 3.8
478      */
479     static UClassID U_EXPORT2 getStaticClassID(void);
480 
481 private:
482     /**
483      * Constructor.
484      * @stable ICU 3.8
485      */
486     DateTimePatternGenerator(UErrorCode & status);
487 
488     /**
489      * Constructor.
490      * @stable ICU 3.8
491      */
492     DateTimePatternGenerator(const Locale& locale, UErrorCode & status);
493 
494     /**
495      * Copy constructor.
496      * @param other DateTimePatternGenerator to copy
497      * @stable ICU 3.8
498      */
499     DateTimePatternGenerator(const DateTimePatternGenerator& other);
500 
501     /**
502      * Default assignment operator.
503      * @param other DateTimePatternGenerator to copy
504      * @stable ICU 3.8
505      */
506     DateTimePatternGenerator& operator=(const DateTimePatternGenerator& other);
507 
508     Locale pLocale;  // pattern locale
509     FormatParser *fp;
510     DateTimeMatcher* dtMatcher;
511     DistanceInfo *distanceInfo;
512     PatternMap *patternMap;
513     UnicodeString appendItemFormats[UDATPG_FIELD_COUNT];
514     UnicodeString appendItemNames[UDATPG_FIELD_COUNT];
515     UnicodeString dateTimeFormat;
516     UnicodeString decimal;
517     DateTimeMatcher *skipMatcher;
518     Hashtable *fAvailableFormatKeyHash;
519     UnicodeString emptyString;
520     UChar fDefaultHourFormatChar;
521 
522     int32_t fAllowedHourFormats[7];  // Actually an array of AllowedHourFormat enum type, ending with UNKNOWN.
523 
524     /* internal flags masks for adjustFieldTypes etc. */
525     enum {
526         kDTPGNoFlags = 0,
527         kDTPGFixFractionalSeconds = 1,
528         kDTPGSkeletonUsesCapJ = 2,
529         kDTPGSkeletonUsesLowB = 3,
530         kDTPGSkeletonUsesCapB = 4
531     };
532 
533     void initData(const Locale &locale, UErrorCode &status);
534     void addCanonicalItems(UErrorCode &status);
535     void addICUPatterns(const Locale& locale, UErrorCode& status);
536     void hackTimes(const UnicodeString& hackPattern, UErrorCode& status);
537     void getCalendarTypeToUse(const Locale& locale, CharString& destination, UErrorCode& err);
538     void consumeShortTimePattern(const UnicodeString& shortTimePattern, UErrorCode& status);
539     void addCLDRData(const Locale& locale, UErrorCode& status);
540     UDateTimePatternConflict addPatternWithSkeleton(const UnicodeString& pattern, const UnicodeString * skeletonToUse, UBool override, UnicodeString& conflictingPattern, UErrorCode& status);
541     void initHashtable(UErrorCode& status);
542     void setDateTimeFromCalendar(const Locale& locale, UErrorCode& status);
543     void setDecimalSymbols(const Locale& locale, UErrorCode& status);
544     UDateTimePatternField getAppendFormatNumber(const char* field) const;
545     UDateTimePatternField getAppendNameNumber(const char* field) const;
546     UnicodeString& getMutableAppendItemName(UDateTimePatternField field);
547     void getAppendName(UDateTimePatternField field, UnicodeString& value);
548     int32_t getCanonicalIndex(const UnicodeString& field);
549     const UnicodeString* getBestRaw(DateTimeMatcher& source, int32_t includeMask, DistanceInfo* missingFields, const PtnSkeleton** specifiedSkeletonPtr = 0);
550     UnicodeString adjustFieldTypes(const UnicodeString& pattern, const PtnSkeleton* specifiedSkeleton, int32_t flags, UDateTimePatternMatchOptions options = UDATPG_MATCH_NO_OPTIONS);
551     UnicodeString getBestAppending(int32_t missingFields, int32_t flags, UDateTimePatternMatchOptions options = UDATPG_MATCH_NO_OPTIONS);
552     int32_t getTopBitNumber(int32_t foundMask);
553     void setAvailableFormat(const UnicodeString &key, UErrorCode& status);
554     UBool isAvailableFormatSet(const UnicodeString &key) const;
555     void copyHashtable(Hashtable *other, UErrorCode &status);
556     UBool isCanonicalItem(const UnicodeString& item) const;
557     static void U_CALLCONV loadAllowedHourFormatsData(UErrorCode &status);
558     void getAllowedHourFormats(const Locale &locale, UErrorCode &status);
559 
560     struct AppendItemFormatsSink;
561     struct AppendItemNamesSink;
562     struct AvailableFormatsSink;
563 } ;// end class DateTimePatternGenerator
564 
565 U_NAMESPACE_END
566 
567 #endif
568