]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/utmscale.c
ICU-6.2.4.tar.gz
[apple/icu.git] / icuSources / i18n / utmscale.c
CommitLineData
374ca955
A
1/*
2*******************************************************************************
3* Copyright (C) 2004, International Business Machines Corporation and
4* others. All Rights Reserved.
5*******************************************************************************
6*/
7
8#include "unicode/utypes.h"
9
10#if !UCONFIG_NO_FORMATTING
11
12#include "unicode/utmscale.h"
13
14#define ticks INT64_C(1)
15#define microseconds (ticks * 10)
16#define milliseconds (microseconds * 1000)
17#define seconds (milliseconds * 1000)
18#define minutes (seconds * 60)
19#define hours (minutes * 60)
20#define days (hours * 24)
21
22#define TIME_SCALE_CHECK(scale,status) \
23 if(scale < 0 || scale >= UDTS_MAX_SCALE) { \
24 *status = U_ILLEGAL_ARGUMENT_ERROR; \
25 return 0; \
26 }
27
28typedef struct
29{
30 int64_t units;
31 int64_t epochOffset;
32
33 int64_t fromMin;
34 int64_t fromMax;
35 int64_t toMin;
36 int64_t toMax;
37
38 int64_t epochOffsetP1;
39 int64_t epochOffsetM1;
40 int64_t unitsRound;
41 int64_t minRound;
42 int64_t maxRound;
43} InternalTimeScaleData;
44
45static const InternalTimeScaleData timeScaleTable[] = {
46 /* units epochOffset fromMin fromMax toMin toMax epochOffsetP1 epochOffsetM1 unitsRound minRound maxRound */
47 {milliseconds, INT64_C(62135769600000), INT64_C(-984472973285477), INT64_C(860201434085477), INT64_C(-9223372036854774999), INT64_C(9223372036854774999), INT64_C(62135769600001), INT64_C(62135769599999), INT64_C(5000), INT64_C(-9223372036854770808), INT64_C(9223372036854770807)},
48 {seconds, INT64_C(62135769600), INT64_C(-984472973285), INT64_C(860201434085), U_INT64_MIN, INT64_C(9223372036854775807), INT64_C(62135769601), INT64_C(62135769599), INT64_C(5000000), INT64_C(-9223372036849775808), INT64_C(9223372036849775807)},
49 {milliseconds, INT64_C(62135769600000), INT64_C(-984472973285477), INT64_C(860201434085477), INT64_C(-9223372036854774999), INT64_C(9223372036854774999), INT64_C(62135769600001), INT64_C(62135769599999), INT64_C(5000), INT64_C(-9223372036854770808), INT64_C(9223372036854770807)},
50 {ticks, INT64_C(504912960000000000), U_INT64_MIN, INT64_C(8718459076854775807), INT64_C(-8718459076854775808), INT64_C(9223372036854775807), INT64_C(504912960000000000), INT64_C(504912960000000000), INT64_C(0), U_INT64_MIN, INT64_C(9223372036854775807)},
51 {ticks, INT64_C(0), U_INT64_MIN, INT64_C(9223372036854775807), U_INT64_MIN, INT64_C(9223372036854775807), INT64_C(0), INT64_C(0), INT64_C(0), U_INT64_MIN, INT64_C(9223372036854775807)},
52 {seconds, INT64_C(60052924800), INT64_C(-982390128485), INT64_C(862284278885), U_INT64_MIN, INT64_C(9223372036854775807), INT64_C(60052924801), INT64_C(60052924799), INT64_C(5000000), INT64_C(-9223372036849775808), INT64_C(9223372036849775807)},
53 {seconds, INT64_C(63114076800), INT64_C(-985451280485), INT64_C(859223126885), U_INT64_MIN, INT64_C(9223372036854775807), INT64_C(63114076801), INT64_C(63114076799), INT64_C(5000000), INT64_C(-9223372036849775808), INT64_C(9223372036849775807)},
54 {days, INT64_C(693596), INT64_C(-11368795), INT64_C(9981603), U_INT64_MIN, INT64_C(9223372036854775807), INT64_C(693597), INT64_C(693595), INT64_C(432000000000), INT64_C(-9223371604854775808), INT64_C(9223371604854775807)},
55 {days, INT64_C(693596), INT64_C(-11368795), INT64_C(9981603), U_INT64_MIN, INT64_C(9223372036854775807), INT64_C(693597), INT64_C(693595), INT64_C(432000000000), INT64_C(-9223371604854775808), INT64_C(9223371604854775807)},
56};
57
58U_CAPI int64_t U_EXPORT2
59utmscale_getTimeScaleValue(UDateTimeScale timeScale, UTimeScaleValue value, UErrorCode *status)
60{
61 const InternalTimeScaleData *internalData;
62
63 if (status == NULL || U_FAILURE(*status)) {
64 return 0;
65 }
66
67 if (timeScale < 0 || timeScale >= UDTS_MAX_SCALE) {
68 *status = U_ILLEGAL_ARGUMENT_ERROR;
69 return 0;
70 }
71
72 internalData = &timeScaleTable[timeScale];
73
74 switch (value)
75 {
76 case UTSV_UNITS_VALUE:
77 return internalData->units;
78
79 case UTSV_EPOCH_OFFSET_VALUE:
80 return internalData->epochOffset;
81
82 case UTSV_FROM_MIN_VALUE:
83 return internalData->fromMin;
84
85 case UTSV_FROM_MAX_VALUE:
86 return internalData->fromMax;
87
88 case UTSV_TO_MIN_VALUE:
89 return internalData->toMin;
90
91 case UTSV_TO_MAX_VALUE:
92 return internalData->toMax;
93
94 case UTSV_EPOCH_OFFSET_PLUS_1_VALUE:
95 return internalData->epochOffsetP1;
96
97 case UTSV_EPOCH_OFFSET_MINUS_1_VALUE:
98 return internalData->epochOffsetM1;
99
100 case UTSV_UNITS_ROUND_VALUE:
101 return internalData->unitsRound;
102
103 case UTSV_MIN_ROUND_VALUE:
104 return internalData->minRound;
105
106 case UTSV_MAX_ROUND_VALUE:
107 return internalData->maxRound;
108
109 default:
110 *status = U_ILLEGAL_ARGUMENT_ERROR;
111 return 0;
112 }
113}
114
115U_CAPI int64_t U_EXPORT2
116utmscale_fromInt64(int64_t otherTime, UDateTimeScale timeScale, UErrorCode *status)
117{
118 const InternalTimeScaleData *data;
119
120 if (status == NULL || U_FAILURE(*status)) {
121 return 0;
122 }
123
124 if (timeScale < 0 || timeScale >= UDTS_MAX_SCALE) {
125 *status = U_ILLEGAL_ARGUMENT_ERROR;
126 return 0;
127 }
128
129 data = &timeScaleTable[timeScale];
130
131 if (otherTime < data->fromMin || otherTime > data->fromMax) {
132 *status = U_ILLEGAL_ARGUMENT_ERROR;
133 return 0;
134 }
135
136 return (otherTime + data->epochOffset) * data->units;
137}
138
139U_CAPI int64_t U_EXPORT2
140utmscale_toInt64(int64_t universalTime, UDateTimeScale timeScale, UErrorCode *status)
141{
142 const InternalTimeScaleData *data;
143
144 if (status == NULL || U_FAILURE(*status)) {
145 return 0;
146 }
147
148 if (timeScale < 0 || timeScale >= UDTS_MAX_SCALE) {
149 *status = U_ILLEGAL_ARGUMENT_ERROR;
150 return 0;
151 }
152
153 data = &timeScaleTable[timeScale];
154
155 if (universalTime < data->toMin || universalTime > data->toMax) {
156 *status = U_ILLEGAL_ARGUMENT_ERROR;
157 return 0;
158 }
159
160 if (universalTime < 0) {
161 if (universalTime < data->minRound) {
162 return (universalTime + data->unitsRound) / data->units - data->epochOffsetP1;
163 }
164
165 return (universalTime - data->unitsRound) / data->units - data->epochOffset;
166 }
167
168 if (universalTime > data->maxRound) {
169 return (universalTime - data->unitsRound) / data->units - data->epochOffsetM1;
170 }
171
172 return (universalTime + data->unitsRound) / data->units - data->epochOffset;
173}
174
175#endif /* #if !UCONFIG_NO_FORMATTING */