185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *******************************************************************************
3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Copyright (C) 2008-2014, Google, International Business Machines Corporation and
427f654740f2a26ad62a5c155af9199af9e69b889claireho * others. All Rights Reserved.
585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *******************************************************************************
685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/tmunit.h"
9fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "uassert.h"
1085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !UCONFIG_NO_FORMATTING
1285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_BEGIN
1485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeUnit)
1685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
1885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
1985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * There are only 7 time units.
2085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * So, TimeUnit could be made as singleton
2185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * (similar to uniset_props.cpp, or unorm.cpp,
2285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * in which a static TimeUnit* array is created, and
2385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * the creatInstance() returns a const TimeUnit*).
2485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * But the constraint is TimeUnit is a data member of Measure.
2585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * But Measure (which is an existing API) does not expect it's "unit" member
2685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * as singleton. Meaure takes ownership of the "unit" member.
2785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * In its constructor, it does not take a const "unit" pointer.
2885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Also, Measure can clone and destruct the "unit" pointer.
2985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * In order to preserve the old behavior and let Measure handle singleton "unit",
3085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * 1. a flag need to be added in Measure;
3185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * 2. a new constructor which takes const "unit" as parameter need to be added,
3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *    and this new constructor will set the flag on.
3385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * 3. clone and destructor need to check upon this flag to distinguish on how
3485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *    to handle the "unit".
3585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *
3685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Since TimeUnit is such a light weight object, comparing with the heavy weight
3785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * format operation, we decided to avoid the above complication.
3885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *
3985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * So, both TimeUnit and CurrencyUnit (the 2 subclasses of MeasureUnit) are
4085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * immutable and non-singleton.
4185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *
4285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Currently, TimeUnitAmount and CurrencyAmount are immutable.
4385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * If an application needs to create a long list of TimeUnitAmount on the same
4485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * time unit but different number, for example,
4585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * 1 hour, 2 hour, 3 hour, ................. 10,000 hour,
4685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * there might be performance hit because 10,000 TimeUnit object,
4785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * although all are the same time unit, will be created in heap and deleted.
4885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho *
4985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * To address this performance issue, if there is any in the future,
5085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * we should and need to change TimeUnitAmount and CurrencyAmount to be
5185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * immutable by allowing a setter on the number.
5285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Or we need to add 2 parallel mutable classes in order to
5385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * preserve the existing API.
5485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Or we can use freezable.
5585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho */
5685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit* U_EXPORT2
5785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::createInstance(TimeUnit::UTimeUnitFields timeUnitField,
5885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                         UErrorCode& status) {
5985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
6085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
6185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
6285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (timeUnitField < 0 || timeUnitField >= UTIMEUNIT_FIELD_COUNT) {
6385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        status = U_ILLEGAL_ARGUMENT_ERROR;
6485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return NULL;
6585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
6685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return new TimeUnit(timeUnitField);
6785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
6885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
6985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
7085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::TimeUnit(TimeUnit::UTimeUnitFields timeUnitField) {
7185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeUnitField = timeUnitField;
72fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    switch (fTimeUnitField) {
73fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTIMEUNIT_YEAR:
74fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initTime("year");
75fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
76fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTIMEUNIT_MONTH:
77fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initTime("month");
78fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
79fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTIMEUNIT_DAY:
80fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initTime("day");
81fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
82fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTIMEUNIT_WEEK:
83fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initTime("week");
84fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
85fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTIMEUNIT_HOUR:
86fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initTime("hour");
87fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
88fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTIMEUNIT_MINUTE:
89fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initTime("minute");
90fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
91fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    case UTIMEUNIT_SECOND:
92fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        initTime("second");
93fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
94fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    default:
95fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        U_ASSERT(false);
96fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius        break;
97fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    }
9885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
9985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::TimeUnit(const TimeUnit& other)
101fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius:   MeasureUnit(other), fTimeUnitField(other.fTimeUnitField) {
10285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
10385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUObject*
10585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::clone() const {
10685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return new TimeUnit(*this);
10785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
10885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit&
11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::operator=(const TimeUnit& other) {
11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (this == &other) {
11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return *this;
11385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
114fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius    MeasureUnit::operator=(other);
11585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    fTimeUnitField = other.fTimeUnitField;
11685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return *this;
11785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
11885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
11985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::UTimeUnitFields
12085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::getTimeUnitField() const {
12185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return fTimeUnitField;
12285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
12385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
12485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoTimeUnit::~TimeUnit() {
12585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
12685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
12785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
12885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_END
12985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
13085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif
131