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