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