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
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnit)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
TimeUnit(TimeUnit::UTimeUnitFields timeUnitField)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
TimeUnit(const TimeUnit & other)100 TimeUnit::TimeUnit(const TimeUnit& other)
101 : MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
102 }
103
104 UObject*
clone() const105 TimeUnit::clone() const {
106 return new TimeUnit(*this);
107 }
108
109 TimeUnit&
operator =(const TimeUnit & other)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
getTimeUnitField() const120 TimeUnit::getTimeUnitField() const {
121 return fTimeUnitField;
122 }
123
~TimeUnit()124 TimeUnit::~TimeUnit() {
125 }
126
127
128 U_NAMESPACE_END
129
130 #endif
131