Home | History | Annotate | Download | only in i18n
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 2008-2014, Google, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  *******************************************************************************
      6  */
      7 
      8 #include "unicode/tmunit.h"
      9 #include "uassert.h"
     10 
     11 #if !UCONFIG_NO_FORMATTING
     12 
     13 U_NAMESPACE_BEGIN
     14 
     15 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnit)
     16 
     17 
     18 /*
     19  * There are only 7 time units.
     20  * So, TimeUnit could be made as singleton
     21  * (similar to uniset_props.cpp, or unorm.cpp,
     22  * in which a static TimeUnit* array is created, and
     23  * the creatInstance() returns a const TimeUnit*).
     24  * But the constraint is TimeUnit is a data member of Measure.
     25  * But Measure (which is an existing API) does not expect it's "unit" member
     26  * as singleton. Meaure takes ownership of the "unit" member.
     27  * In its constructor, it does not take a const "unit" pointer.
     28  * Also, Measure can clone and destruct the "unit" pointer.
     29  * In order to preserve the old behavior and let Measure handle singleton "unit",
     30  * 1. a flag need to be added in Measure;
     31  * 2. a new constructor which takes const "unit" as parameter need to be added,
     32  *    and this new constructor will set the flag on.
     33  * 3. clone and destructor need to check upon this flag to distinguish on how
     34  *    to handle the "unit".
     35  *
     36  * Since TimeUnit is such a light weight object, comparing with the heavy weight
     37  * format operation, we decided to avoid the above complication.
     38  *
     39  * So, both TimeUnit and CurrencyUnit (the 2 subclasses of MeasureUnit) are
     40  * immutable and non-singleton.
     41  *
     42  * Currently, TimeUnitAmount and CurrencyAmount are immutable.
     43  * If an application needs to create a long list of TimeUnitAmount on the same
     44  * time unit but different number, for example,
     45  * 1 hour, 2 hour, 3 hour, ................. 10,000 hour,
     46  * there might be performance hit because 10,000 TimeUnit object,
     47  * although all are the same time unit, will be created in heap and deleted.
     48  *
     49  * To address this performance issue, if there is any in the future,
     50  * we should and need to change TimeUnitAmount and CurrencyAmount to be
     51  * immutable by allowing a setter on the number.
     52  * Or we need to add 2 parallel mutable classes in order to
     53  * preserve the existing API.
     54  * Or we can use freezable.
     55  */
     56 TimeUnit* U_EXPORT2
     57 TimeUnit::createInstance(TimeUnit::UTimeUnitFields timeUnitField,
     58                          UErrorCode& status) {
     59     if (U_FAILURE(status)) {
     60         return NULL;
     61     }
     62     if (timeUnitField < 0 || timeUnitField >= UTIMEUNIT_FIELD_COUNT) {
     63         status = U_ILLEGAL_ARGUMENT_ERROR;
     64         return NULL;
     65     }
     66     return new TimeUnit(timeUnitField);
     67 }
     68 
     69 
     70 TimeUnit::TimeUnit(TimeUnit::UTimeUnitFields timeUnitField) {
     71     fTimeUnitField = timeUnitField;
     72     switch (fTimeUnitField) {
     73     case UTIMEUNIT_YEAR:
     74         initTime("year");
     75         break;
     76     case UTIMEUNIT_MONTH:
     77         initTime("month");
     78         break;
     79     case UTIMEUNIT_DAY:
     80         initTime("day");
     81         break;
     82     case UTIMEUNIT_WEEK:
     83         initTime("week");
     84         break;
     85     case UTIMEUNIT_HOUR:
     86         initTime("hour");
     87         break;
     88     case UTIMEUNIT_MINUTE:
     89         initTime("minute");
     90         break;
     91     case UTIMEUNIT_SECOND:
     92         initTime("second");
     93         break;
     94     default:
     95         U_ASSERT(false);
     96         break;
     97     }
     98 }
     99 
    100 TimeUnit::TimeUnit(const TimeUnit& other)
    101 :   MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
    102 }
    103 
    104 UObject*
    105 TimeUnit::clone() const {
    106     return new TimeUnit(*this);
    107 }
    108 
    109 TimeUnit&
    110 TimeUnit::operator=(const TimeUnit& other) {
    111     if (this == &other) {
    112         return *this;
    113     }
    114     MeasureUnit::operator=(other);
    115     fTimeUnitField = other.fTimeUnitField;
    116     return *this;
    117 }
    118 
    119 TimeUnit::UTimeUnitFields
    120 TimeUnit::getTimeUnitField() const {
    121     return fTimeUnitField;
    122 }
    123 
    124 TimeUnit::~TimeUnit() {
    125 }
    126 
    127 
    128 U_NAMESPACE_END
    129 
    130 #endif
    131