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 "formattedval_impl.h"
22
23U_NAMESPACE_USE
24
25
26// Magic number: FDIV in ASCII
27UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
28 FormattedDateInterval,
29 UFormattedDateInterval,
30 UFormattedDateIntervalImpl,
31 UFormattedDateIntervalApiHelper,
32 udtitvfmt,
33 0x46444956)
34
35
36U_CAPI UDateIntervalFormat* U_EXPORT2
37udtitvfmt_open(const char* locale,
38 const UChar* skeleton,
39 int32_t skeletonLength,
40 const UChar* tzID,
41 int32_t tzIDLength,
42 UErrorCode* status)
43{
44 if (U_FAILURE(*status)) {
45 return NULL;
46 }
47 if ((skeleton == NULL ? skeletonLength != 0 : skeletonLength < -1) ||
48 (tzID == NULL ? tzIDLength != 0 : tzIDLength < -1)
49 ) {
50 *status = U_ILLEGAL_ARGUMENT_ERROR;
51 return NULL;
52 }
53 UnicodeString skel((UBool)(skeletonLength == -1), skeleton, skeletonLength);
54 LocalPointer<DateIntervalFormat> formatter(
55 DateIntervalFormat::createInstance(skel, Locale(locale), *status));
56 if (U_FAILURE(*status)) {
57 return NULL;
58 }
59 if(tzID != 0) {
60 TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength));
61 if(zone == NULL) {
62 *status = U_MEMORY_ALLOCATION_ERROR;
63 return NULL;
64 }
65 formatter->adoptTimeZone(zone);
66 }
67 return (UDateIntervalFormat*)formatter.orphan();
68}
69
70
71U_CAPI void U_EXPORT2
72udtitvfmt_close(UDateIntervalFormat *formatter)
73{
74 delete (DateIntervalFormat*)formatter;
75}
76
77
78U_CAPI int32_t U_EXPORT2
79udtitvfmt_format(const UDateIntervalFormat* formatter,
80 UDate fromDate,
81 UDate toDate,
82 UChar* result,
83 int32_t resultCapacity,
84 UFieldPosition* position,
85 UErrorCode* status)
86{
87 if (U_FAILURE(*status)) {
88 return -1;
89 }
90 if (result == NULL ? resultCapacity != 0 : resultCapacity < 0) {
91 *status = U_ILLEGAL_ARGUMENT_ERROR;
92 return 0;
93 }
94 UnicodeString res;
95 if (result != NULL) {
96 // NULL destination for pure preflighting: empty dummy string
97 // otherwise, alias the destination buffer (copied from udat_format)
98 res.setTo(result, 0, resultCapacity);
99 }
100 FieldPosition fp;
101 if (position != 0) {
102 fp.setField(position->field);
103 }
104
105 DateInterval interval = DateInterval(fromDate,toDate);
106 ((const DateIntervalFormat*)formatter)->format( &interval, res, fp, *status );
107 if (U_FAILURE(*status)) {
108 return -1;
109 }
110 if (position != 0) {
111 position->beginIndex = fp.getBeginIndex();
112 position->endIndex = fp.getEndIndex();
113 }
114
115 return res.extract(result, resultCapacity, *status);
116}
117
118
119U_DRAFT void U_EXPORT2
120udtitvfmt_formatToResult(
121 const UDateIntervalFormat* formatter,
122 UDate fromDate,
123 UDate toDate,
124 UFormattedDateInterval* result,
125 UErrorCode* status) {
126 if (U_FAILURE(*status)) {
127 return;
128 }
129 auto* resultImpl = UFormattedDateIntervalApiHelper::validate(result, *status);
130 DateInterval interval = DateInterval(fromDate,toDate);
131 if (resultImpl != nullptr) {
132 resultImpl->fImpl = reinterpret_cast<const DateIntervalFormat*>(formatter)
133 ->formatToValue(interval, *status);
134 }
135}
136
137U_DRAFT void U_EXPORT2
138udtitvfmt_formatCalendarToResult(
139 const UDateIntervalFormat* formatter,
140 UCalendar* fromCalendar,
141 UCalendar* toCalendar,
142 UFormattedDateInterval* result,
143 UErrorCode* status) {
144 if (U_FAILURE(*status)) {
145 return;
146 }
147 auto* resultImpl = UFormattedDateIntervalApiHelper::validate(result, *status);
148 if (resultImpl != nullptr) {
149 resultImpl->fImpl = reinterpret_cast<const DateIntervalFormat*>(formatter)
150 ->formatToValue(*(Calendar *)fromCalendar, *(Calendar *)toCalendar, *status);
151 }
152}
153
154
155#endif /* #if !UCONFIG_NO_FORMATTING */
156