• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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