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
23 U_NAMESPACE_USE
24
25
26 // Magic number: FDIV in ASCII
27 UPRV_FORMATTED_VALUE_CAPI_AUTO_IMPL(
28 FormattedDateInterval,
29 UFormattedDateInterval,
30 UFormattedDateIntervalImpl,
31 UFormattedDateIntervalApiHelper,
32 udtitvfmt,
33 0x46444956)
34
35
36 U_CAPI UDateIntervalFormat* U_EXPORT2
udtitvfmt_open(const char * locale,const UChar * skeleton,int32_t skeletonLength,const UChar * tzID,int32_t tzIDLength,UErrorCode * status)37 udtitvfmt_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
71 U_CAPI void U_EXPORT2
udtitvfmt_close(UDateIntervalFormat * formatter)72 udtitvfmt_close(UDateIntervalFormat *formatter)
73 {
74 delete (DateIntervalFormat*)formatter;
75 }
76
77
78 U_CAPI int32_t U_EXPORT2
udtitvfmt_format(const UDateIntervalFormat * formatter,UDate fromDate,UDate toDate,UChar * result,int32_t resultCapacity,UFieldPosition * position,UErrorCode * status)79 udtitvfmt_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
119 U_DRAFT void U_EXPORT2
udtitvfmt_formatToResult(const UDateIntervalFormat * formatter,UFormattedDateInterval * result,UDate fromDate,UDate toDate,UErrorCode * status)120 udtitvfmt_formatToResult(
121 const UDateIntervalFormat* formatter,
122 UFormattedDateInterval* result,
123 UDate fromDate,
124 UDate toDate,
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 resultImpl->fImpl = reinterpret_cast<const DateIntervalFormat*>(formatter)
132 ->formatToValue(interval, *status);
133 }
134
135
136 #endif /* #if !UCONFIG_NO_FORMATTING */
137