2 * Copyright 2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Oliver Tappe <zooey@hirschkaefer.de>
10 #include <unicode/uversion.h>
11 #include <DurationFormat.h>
15 #include <unicode/gregocal.h>
16 #include <unicode/utypes.h>
19 #include <LocaleRoster.h>
22 #include <TimeZonePrivate.h>
25 // maps our unit element to the corresponding ICU unit
26 static const UCalendarDateFields skUnitMap
[] = {
37 BDurationFormat::BDurationFormat(const BLanguage
& language
,
38 const BFormattingConventions
& conventions
, const BString
& separator
)
40 Inherited(language
, conventions
),
41 fSeparator(separator
),
42 fTimeUnitFormat(language
, conventions
)
44 UErrorCode icuStatus
= U_ZERO_ERROR
;
45 fCalendar
= new GregorianCalendar(icuStatus
);
46 if (fCalendar
== NULL
) {
47 fInitStatus
= B_NO_MEMORY
;
53 BDurationFormat::BDurationFormat(const BString
& separator
)
56 fSeparator(separator
),
59 UErrorCode icuStatus
= U_ZERO_ERROR
;
60 fCalendar
= new GregorianCalendar(icuStatus
);
61 if (fCalendar
== NULL
) {
62 fInitStatus
= B_NO_MEMORY
;
68 BDurationFormat::BDurationFormat(const BDurationFormat
& other
)
71 fSeparator(other
.fSeparator
),
72 fTimeUnitFormat(other
.fTimeUnitFormat
),
73 fCalendar(other
.fCalendar
!= NULL
74 ? new GregorianCalendar(*other
.fCalendar
) : NULL
)
76 if (fCalendar
== NULL
&& other
.fCalendar
!= NULL
)
77 fInitStatus
= B_NO_MEMORY
;
81 BDurationFormat::~BDurationFormat()
88 BDurationFormat::SetSeparator(const BString
& separator
)
90 fSeparator
= separator
;
95 BDurationFormat::SetTimeZone(const BTimeZone
* timeZone
)
97 if (fCalendar
== NULL
)
100 BTimeZone::Private zonePrivate
;
101 if (timeZone
== NULL
) {
102 BTimeZone defaultTimeZone
;
104 = BLocaleRoster::Default()->GetDefaultTimeZone(&defaultTimeZone
);
107 zonePrivate
.SetTo(&defaultTimeZone
);
109 zonePrivate
.SetTo(timeZone
);
111 TimeZone
* icuTimeZone
= zonePrivate
.ICUTimeZone();
112 if (icuTimeZone
!= NULL
)
113 fCalendar
->setTimeZone(*icuTimeZone
);
120 BDurationFormat::Format(BString
& buffer
, const bigtime_t startValue
,
121 const bigtime_t stopValue
, time_unit_style style
) const
123 UErrorCode icuStatus
= U_ZERO_ERROR
;
124 fCalendar
->setTime((UDate
)startValue
/ 1000, icuStatus
);
125 if (!U_SUCCESS(icuStatus
))
128 UDate stop
= (UDate
)stopValue
/ 1000;
129 bool needSeparator
= false;
130 for (int unit
= 0; unit
<= B_TIME_UNIT_LAST
; ++unit
) {
132 = fCalendar
->fieldDifference(stop
, skUnitMap
[unit
], icuStatus
);
133 if (!U_SUCCESS(icuStatus
))
138 buffer
.Append(fSeparator
);
140 needSeparator
= true;
141 status_t status
= fTimeUnitFormat
.Format(buffer
, delta
,
142 (time_unit_element
)unit
, style
);