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