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
,
39 const BString
& separator
, const time_unit_style style
)
41 Inherited(language
, conventions
),
42 fSeparator(separator
),
43 fTimeUnitFormat(language
, conventions
, style
)
45 UErrorCode icuStatus
= U_ZERO_ERROR
;
46 fCalendar
= new GregorianCalendar(icuStatus
);
47 if (fCalendar
== NULL
) {
48 fInitStatus
= B_NO_MEMORY
;
54 BDurationFormat::BDurationFormat(const BString
& separator
,
55 const time_unit_style style
)
58 fSeparator(separator
),
59 fTimeUnitFormat(style
)
61 UErrorCode icuStatus
= U_ZERO_ERROR
;
62 fCalendar
= new GregorianCalendar(icuStatus
);
63 if (fCalendar
== NULL
) {
64 fInitStatus
= B_NO_MEMORY
;
70 BDurationFormat::BDurationFormat(const BDurationFormat
& other
)
73 fSeparator(other
.fSeparator
),
74 fTimeUnitFormat(other
.fTimeUnitFormat
),
75 fCalendar(other
.fCalendar
!= NULL
76 ? new GregorianCalendar(*other
.fCalendar
) : NULL
)
78 if (fCalendar
== NULL
&& other
.fCalendar
!= NULL
)
79 fInitStatus
= B_NO_MEMORY
;
83 BDurationFormat::~BDurationFormat()
90 BDurationFormat::SetSeparator(const BString
& separator
)
92 fSeparator
= separator
;
97 BDurationFormat::SetTimeZone(const BTimeZone
* timeZone
)
99 if (fCalendar
== NULL
)
102 BTimeZone::Private zonePrivate
;
103 if (timeZone
== NULL
) {
104 BTimeZone defaultTimeZone
;
106 = BLocaleRoster::Default()->GetDefaultTimeZone(&defaultTimeZone
);
109 zonePrivate
.SetTo(&defaultTimeZone
);
111 zonePrivate
.SetTo(timeZone
);
113 TimeZone
* icuTimeZone
= zonePrivate
.ICUTimeZone();
114 if (icuTimeZone
!= NULL
)
115 fCalendar
->setTimeZone(*icuTimeZone
);
122 BDurationFormat::Format(BString
& buffer
, const bigtime_t startValue
,
123 const bigtime_t stopValue
) const
125 UErrorCode icuStatus
= U_ZERO_ERROR
;
126 fCalendar
->setTime((UDate
)startValue
/ 1000, icuStatus
);
127 if (!U_SUCCESS(icuStatus
))
130 UDate stop
= (UDate
)stopValue
/ 1000;
131 bool needSeparator
= false;
132 for (int unit
= 0; unit
<= B_TIME_UNIT_LAST
; ++unit
) {
134 = fCalendar
->fieldDifference(stop
, skUnitMap
[unit
], icuStatus
);
135 if (!U_SUCCESS(icuStatus
))
140 buffer
.Append(fSeparator
);
142 needSeparator
= true;
143 status_t status
= fTimeUnitFormat
.Format(buffer
, delta
,
144 (time_unit_element
)unit
);