1/*
2 *******************************************************************************
3 * Copyright (C) 2008-2011, Google, International Business Machines Corporation
4 * and others. All Rights Reserved.
5 *******************************************************************************
6 */
7
8#ifndef __TMUTFMT_H__
9#define __TMUTFMT_H__
10
11#include "unicode/utypes.h"
12
13/**
14 * \file
15 * \brief C++ API: Format and parse duration in single time unit
16 */
17
18
19#if !UCONFIG_NO_FORMATTING
20
21#include "unicode/unistr.h"
22#include "unicode/tmunit.h"
23#include "unicode/tmutamt.h"
24#include "unicode/measfmt.h"
25#include "unicode/numfmt.h"
26#include "unicode/plurrule.h"
27
28/**
29 * Constants for various styles.
30 * There are 2 styles: full name and abbreviated name.
31 * For example, for English, the full name for hour duration is "3 hours",
32 * and the abbreviated name is "3 hrs".
33 * @draft ICU 4.8
34 */
35enum UTimeUnitFormatStyle {
36    /** @draft ICU 4.8 */
37    UTMUTFMT_FULL_STYLE,
38    /** @draft ICU 4.8 */
39    UTMUTFMT_ABBREVIATED_STYLE,
40    /** @draft ICU 4.8 */
41    UTMUTFMT_FORMAT_STYLE_COUNT
42};
43typedef enum UTimeUnitFormatStyle UTimeUnitFormatStyle; /**< @draft ICU 4.8 */
44
45U_NAMESPACE_BEGIN
46
47class Hashtable;
48
49
50/**
51 * Format or parse a TimeUnitAmount, using plural rules for the units where available.
52 *
53 * <P>
54 * Code Sample:
55 * <pre>
56 *   // create time unit amount instance - a combination of Number and time unit
57 *   UErrorCode status = U_ZERO_ERROR;
58 *   TimeUnitAmount* source = new TimeUnitAmount(2, TimeUnit::UTIMEUNIT_YEAR, status);
59 *   // create time unit format instance
60 *   TimeUnitFormat* format = new TimeUnitFormat(Locale("en"), status);
61 *   // format a time unit amount
62 *   UnicodeString formatted;
63 *   Formattable formattable;
64 *   if (U_SUCCESS(status)) {
65 *       formattable.adoptObject(source);
66 *       formatted = ((Format*)format)->format(formattable, formatted, status);
67 *       Formattable result;
68 *       ((Format*)format)->parseObject(formatted, result, status);
69 *       if (U_SUCCESS(status)) {
70 *           assert (result == formattable);
71 *       }
72 *   }
73 * </pre>
74 *
75 * <P>
76 * @see TimeUnitAmount
77 * @see TimeUnitFormat
78 * @draft ICU 4.2
79 */
80class U_I18N_API TimeUnitFormat: public MeasureFormat {
81public:
82
83    /**
84     * Create TimeUnitFormat with default locale, and full name style.
85     * Use setLocale and/or setFormat to modify.
86     * @stable ICU 4.2
87     */
88    TimeUnitFormat(UErrorCode& status);
89
90    /**
91     * Create TimeUnitFormat given locale, and full name style.
92     * @stable ICU 4.2
93     */
94    TimeUnitFormat(const Locale& locale, UErrorCode& status);
95
96    /**
97     * Create TimeUnitFormat given locale and style.
98     * @draft ICU 4.8
99     */
100    TimeUnitFormat(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status);
101
102    /**
103     * Copy constructor.
104     * @stable ICU 4.2
105     */
106    TimeUnitFormat(const TimeUnitFormat&);
107
108    /**
109     * deconstructor
110     * @stable ICU 4.2
111     */
112    virtual ~TimeUnitFormat();
113
114    /**
115     * Clone this Format object polymorphically. The caller owns the result and
116     * should delete it when done.
117     * @return    A copy of the object.
118     * @stable ICU 4.2
119     */
120    virtual Format* clone(void) const;
121
122    /**
123     * Assignment operator
124     * @stable ICU 4.2
125     */
126    TimeUnitFormat& operator=(const TimeUnitFormat& other);
127
128
129    /**
130     * Return true if the given Format objects are semantically equal. Objects
131     * of different subclasses are considered unequal.
132     * @param other    the object to be compared with.
133     * @return         true if the given Format objects are semantically equal.
134     * @stable ICU 4.2
135     */
136    virtual UBool operator==(const Format& other) const;
137
138    /**
139     * Return true if the given Format objects are not semantically equal.
140     * Objects of different subclasses are considered unequal.
141     * @param other the object to be compared with.
142     * @return      true if the given Format objects are not semantically equal.
143     * @stable ICU 4.2
144     */
145    UBool operator!=(const Format& other) const;
146
147    /**
148     * Set the locale used for formatting or parsing.
149     * @param locale  the locale to be set
150     * @param status  output param set to success/failure code on exit
151     * @stable ICU 4.2
152     */
153    void setLocale(const Locale& locale, UErrorCode& status);
154
155
156    /**
157     * Set the number format used for formatting or parsing.
158     * @param format  the number formatter to be set
159     * @param status  output param set to success/failure code on exit
160     * @stable ICU 4.2
161     */
162    void setNumberFormat(const NumberFormat& format, UErrorCode& status);
163
164
165    using MeasureFormat::format;
166
167    /**
168     * Format a TimeUnitAmount.
169     * If the formattable object is not a time unit amount object,
170     * or the number in time unit amount is not a double type or long type
171     * numeric, it returns a failing status: U_ILLEGAL_ARGUMENT_ERROR.
172     * @see Format#format(const Formattable&, UnicodeString&, FieldPosition&,  UErrorCode&) const
173     * @stable ICU 4.2
174     */
175    virtual UnicodeString& format(const Formattable& obj,
176                                  UnicodeString& toAppendTo,
177                                  FieldPosition& pos,
178                                  UErrorCode& status) const;
179
180    /**
181     * Parse a TimeUnitAmount.
182     * @see Format#parseObject(const UnicodeString&, Formattable&, ParsePosition&) const;
183     * @stable ICU 4.2
184     */
185    virtual void parseObject(const UnicodeString& source,
186                             Formattable& result,
187                             ParsePosition& pos) const;
188
189    /**
190     * Return the class ID for this class. This is useful only for comparing to
191     * a return value from getDynamicClassID(). For example:
192     * <pre>
193     * .   Base* polymorphic_pointer = createPolymorphicObject();
194     * .   if (polymorphic_pointer->getDynamicClassID() ==
195     * .       erived::getStaticClassID()) ...
196     * </pre>
197     * @return          The class ID for all objects of this class.
198     * @stable ICU 4.2
199     */
200    static UClassID U_EXPORT2 getStaticClassID(void);
201
202    /**
203     * Returns a unique class ID POLYMORPHICALLY. Pure virtual override. This
204     * method is to implement a simple version of RTTI, since not all C++
205     * compilers support genuine RTTI. Polymorphic operator==() and clone()
206     * methods call this method.
207     *
208     * @return          The class ID for this object. All objects of a
209     *                  given class have the same class ID.  Objects of
210     *                  other classes have different class IDs.
211     * @stable ICU 4.2
212     */
213    virtual UClassID getDynamicClassID(void) const;
214
215private:
216    NumberFormat* fNumberFormat;
217    Locale        fLocale;
218    Hashtable*    fTimeUnitToCountToPatterns[TimeUnit::UTIMEUNIT_FIELD_COUNT];
219    PluralRules*  fPluralRules;
220    UTimeUnitFormatStyle fStyle;
221
222    void create(const Locale& locale, UTimeUnitFormatStyle style, UErrorCode& status);
223
224    // it might actually be simpler to make them Decimal Formats later.
225    // initialize all private data members
226    void setup(UErrorCode& status);
227
228    // initialize data member without fill in data for fTimeUnitToCountToPattern
229    void initDataMembers(UErrorCode& status);
230
231    // initialize fTimeUnitToCountToPatterns from current locale's resource.
232    void readFromCurrentLocale(UTimeUnitFormatStyle style, const char* key, UErrorCode& status);
233
234    // check completeness of fTimeUnitToCountToPatterns against all time units,
235    // and all plural rules, fill in fallback as necessary.
236    void checkConsistency(UTimeUnitFormatStyle style, const char* key, UErrorCode& status);
237
238    // fill in fTimeUnitToCountToPatterns from locale fall-back chain
239    void searchInLocaleChain(UTimeUnitFormatStyle style, const char* key, const char* localeName,
240                             TimeUnit::UTimeUnitFields field, const UnicodeString&,
241                             const char*, Hashtable*, UErrorCode&);
242
243    // initialize hash table
244    Hashtable* initHash(UErrorCode& status);
245
246    // delete hash table
247    void deleteHash(Hashtable* htable);
248
249    // copy hash table
250    void copyHash(const Hashtable* source, Hashtable* target, UErrorCode& status);
251    // get time unit name, such as "year", from time unit field enum, such as
252    // UTIMEUNIT_YEAR.
253    static const char* getTimeUnitName(TimeUnit::UTimeUnitFields field, UErrorCode& status);
254};
255
256
257
258inline UBool
259TimeUnitFormat::operator!=(const Format& other) const  {
260    return !operator==(other);
261}
262
263
264
265U_NAMESPACE_END
266
267#endif /* #if !UCONFIG_NO_FORMATTING */
268
269#endif // __TMUTFMT_H__
270//eof
271