1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *****************************************************************************************
5 * Copyright (C) 2010-2011, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *****************************************************************************************
8 */
9
10 #include "unicode/utypes.h"
11
12 #if !UCONFIG_NO_FORMATTING
13
14 #include "unicode/udateintervalformat.h"
15 #include "unicode/dtitvfmt.h"
16 #include "unicode/dtintrv.h"
17 #include "unicode/localpointer.h"
18 #include "unicode/timezone.h"
19 #include "unicode/locid.h"
20 #include "unicode/unistr.h"
21 #include "unicode/udisplaycontext.h"
22 #include "formattedval_impl.h"
23
24 U_NAMESPACE_USE
25
26
27 // Magic number: FDIV in ASCII
28 UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
29 FormattedDateInterval,
30 UFormattedDateInterval,
31 UFormattedDateIntervalImpl,
32 UFormattedDateIntervalApiHelper,
33 udtitvfmt,
34 0x46444956)
35
36
37 U_CAPI UDateIntervalFormat* U_EXPORT2
udtitvfmt_open(const char * locale,const UChar * skeleton,int32_t skeletonLength,const UChar * tzID,int32_t tzIDLength,UErrorCode * status)38 udtitvfmt_open(const char* locale,
39 const UChar* skeleton,
40 int32_t skeletonLength,
41 const UChar* tzID,
42 int32_t tzIDLength,
43 UErrorCode* status)
44 {
45 if (U_FAILURE(*status)) {
46 return NULL;
47 }
48 if ((skeleton == NULL ? skeletonLength != 0 : skeletonLength < -1) ||
49 (tzID == NULL ? tzIDLength != 0 : tzIDLength < -1)
50 ) {
51 *status = U_ILLEGAL_ARGUMENT_ERROR;
52 return NULL;
53 }
54 UnicodeString skel((UBool)(skeletonLength == -1), skeleton, skeletonLength);
55 LocalPointer<DateIntervalFormat> formatter(
56 DateIntervalFormat::createInstance(skel, Locale(locale), *status));
57 if (U_FAILURE(*status)) {
58 return NULL;
59 }
60 if(tzID != 0) {
61 TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength));
62 if(zone == NULL) {
63 *status = U_MEMORY_ALLOCATION_ERROR;
64 return NULL;
65 }
66 formatter->adoptTimeZone(zone);
67 }
68 return (UDateIntervalFormat*)formatter.orphan();
69 }
70
71
72 U_CAPI void U_EXPORT2
udtitvfmt_close(UDateIntervalFormat * formatter)73 udtitvfmt_close(UDateIntervalFormat *formatter)
74 {
75 delete (DateIntervalFormat*)formatter;
76 }
77
78
79 U_CAPI int32_t U_EXPORT2
udtitvfmt_format(const UDateIntervalFormat * formatter,UDate fromDate,UDate toDate,UChar * result,int32_t resultCapacity,UFieldPosition * position,UErrorCode * status)80 udtitvfmt_format(const UDateIntervalFormat* formatter,
81 UDate fromDate,
82 UDate toDate,
83 UChar* result,
84 int32_t resultCapacity,
85 UFieldPosition* position,
86 UErrorCode* status)
87 {
88 if (U_FAILURE(*status)) {
89 return -1;
90 }
91 if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
92 *status = U_ILLEGAL_ARGUMENT_ERROR;
93 return 0;
94 }
95 UnicodeString res;
96 if (result != NULL) {
97 // NULL destination for pure preflighting: empty dummy string
98 // otherwise, alias the destination buffer (copied from udat_format)
99 res.setTo(result, 0, resultCapacity);
100 }
101 FieldPosition fp;
102 if (position != 0) {
103 fp.setField(position->field);
104 }
105
106 DateInterval interval = DateInterval(fromDate,toDate);
107 ((const DateIntervalFormat*)formatter)->format( &interval, res, fp, *status );
108 if (U_FAILURE(*status)) {
109 return -1;
110 }
111 if (position != 0) {
112 position->beginIndex = fp.getBeginIndex();
113 position->endIndex = fp.getEndIndex();
114 }
115
116 return res.extract(result, resultCapacity, *status);
117 }
118
119
120 U_CAPI void U_EXPORT2
udtitvfmt_formatToResult(const UDateIntervalFormat * formatter,UDate fromDate,UDate toDate,UFormattedDateInterval * result,UErrorCode * status)121 udtitvfmt_formatToResult(
122 const UDateIntervalFormat* formatter,
123 UDate fromDate,
124 UDate toDate,
125 UFormattedDateInterval* result,
126 UErrorCode* status) {
127 if (U_FAILURE(*status)) {
128 return;
129 }
130 auto* resultImpl = UFormattedDateIntervalApiHelper::validate(result, *status);
131 DateInterval interval = DateInterval(fromDate,toDate);
132 if (resultImpl != nullptr) {
133 resultImpl->fImpl = reinterpret_cast<const DateIntervalFormat*>(formatter)
134 ->formatToValue(interval, *status);
135 }
136 }
137
138 U_CAPI void U_EXPORT2
udtitvfmt_formatCalendarToResult(const UDateIntervalFormat * formatter,UCalendar * fromCalendar,UCalendar * toCalendar,UFormattedDateInterval * result,UErrorCode * status)139 udtitvfmt_formatCalendarToResult(
140 const UDateIntervalFormat* formatter,
141 UCalendar* fromCalendar,
142 UCalendar* toCalendar,
143 UFormattedDateInterval* result,
144 UErrorCode* status) {
145 if (U_FAILURE(*status)) {
146 return;
147 }
148 auto* resultImpl = UFormattedDateIntervalApiHelper::validate(result, *status);
149 if (resultImpl != nullptr) {
150 resultImpl->fImpl = reinterpret_cast<const DateIntervalFormat*>(formatter)
151 ->formatToValue(*(Calendar *)fromCalendar, *(Calendar *)toCalendar, *status);
152 }
153 }
154
155 U_CAPI void U_EXPORT2
udtitvfmt_setContext(UDateIntervalFormat * formatter,UDisplayContext value,UErrorCode * status)156 udtitvfmt_setContext(UDateIntervalFormat* formatter,
157 UDisplayContext value,
158 UErrorCode* status) {
159 if (U_FAILURE(*status)) {
160 return;
161 }
162 reinterpret_cast<DateIntervalFormat*>(formatter)->setContext( value, *status );
163 }
164
165 U_CAPI UDisplayContext U_EXPORT2
udtitvfmt_getContext(const UDateIntervalFormat * formatter,UDisplayContextType type,UErrorCode * status)166 udtitvfmt_getContext(const UDateIntervalFormat* formatter,
167 UDisplayContextType type,
168 UErrorCode* status) {
169 if (U_FAILURE(*status)) {
170 return (UDisplayContext)0;
171 }
172 return reinterpret_cast<const DateIntervalFormat*>(formatter)->getContext( type, *status );
173 }
174
175
176 #endif /* #if !UCONFIG_NO_FORMATTING */
177