1 // Copyright (C) 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
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnit)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
TimeUnit(TimeUnit::UTimeUnitFields timeUnitField)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
TimeUnit(const TimeUnit & other)102 TimeUnit::TimeUnit(const TimeUnit& other)
103 : MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
104 }
105
106 UObject*
clone() const107 TimeUnit::clone() const {
108 return new TimeUnit(*this);
109 }
110
111 TimeUnit&
operator =(const TimeUnit & other)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
getTimeUnitField() const122 TimeUnit::getTimeUnitField() const {
123 return fTimeUnitField;
124 }
125
~TimeUnit()126 TimeUnit::~TimeUnit() {
127 }
128
129
130 U_NAMESPACE_END
131
132 #endif
133