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