Home | History | Annotate | Download | only in unicode
      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  */
     35 enum 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 };
     43 typedef enum UTimeUnitFormatStyle UTimeUnitFormatStyle; /**< @draft ICU 4.8 */
     44 
     45 U_NAMESPACE_BEGIN
     46 
     47 class 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  */
     80 class U_I18N_API TimeUnitFormat: public MeasureFormat {
     81 public:
     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 
    215 private:
    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 
    258 inline UBool
    259 TimeUnitFormat::operator!=(const Format& other) const  {
    260     return !operator==(other);
    261 }
    262 
    263 
    264 
    265 U_NAMESPACE_END
    266 
    267 #endif /* #if !UCONFIG_NO_FORMATTING */
    268 
    269 #endif // __TMUTFMT_H__
    270 //eof
    271