1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2004-2006, International Business Machines Corporation and
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* others. All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*******************************************************************************
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utmscale.h"
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define ticks        INT64_C(1)
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define microseconds (ticks * 10)
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define milliseconds (microseconds * 1000)
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define seconds      (milliseconds * 1000)
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define minutes      (seconds * 60)
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define hours        (minutes * 60)
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define days         (hours * 24)
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Constants generated by ICU4J com.ibm.icu.dev.tool.timescale.GenerateCTimeScaleData. */
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int64_t timeScaleTable[UDTS_MAX_SCALE][UTSV_MAX_SCALE_VALUE] = {
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  /*    units             epochOffset                     fromMin                        fromMax                            toMin                        toMax                    epochOffsetP1                epochOffsetM1              unitsRound                    minRound                     maxRound          */
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {milliseconds, INT64_C(62135596800000),     INT64_C(-984472800485477),     INT64_C(860201606885477),     INT64_C(-9223372036854774999), INT64_C(9223372036854774999), INT64_C(62135596800001),     INT64_C(62135596799999),     INT64_C(5000),         INT64_C(-9223372036854770808), INT64_C(9223372036854770807)},
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {seconds,      INT64_C(62135596800),        INT64_C(-984472800485),        INT64_C(860201606885),        U_INT64_MIN,                   U_INT64_MAX,                  INT64_C(62135596801),        INT64_C(62135596799),        INT64_C(5000000),      INT64_C(-9223372036849775808), INT64_C(9223372036849775807)},
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {milliseconds, INT64_C(62135596800000),     INT64_C(-984472800485477),     INT64_C(860201606885477),     INT64_C(-9223372036854774999), INT64_C(9223372036854774999), INT64_C(62135596800001),     INT64_C(62135596799999),     INT64_C(5000),         INT64_C(-9223372036854770808), INT64_C(9223372036854770807)},
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {ticks,        INT64_C(504911232000000000), U_INT64_MIN,                   INT64_C(8718460804854775807), INT64_C(-8718460804854775808), U_INT64_MAX,                  INT64_C(504911232000000000), INT64_C(504911232000000000), INT64_C(0),            U_INT64_MIN,                   U_INT64_MAX},
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {ticks,        INT64_C(0),                  U_INT64_MIN,                   U_INT64_MAX,                  U_INT64_MIN,                   U_INT64_MAX,                  INT64_C(0),                  INT64_C(0),                  INT64_C(0),            U_INT64_MIN,                   U_INT64_MAX},
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {seconds,      INT64_C(60052752000),        INT64_C(-982389955685),        INT64_C(862284451685),        U_INT64_MIN,                   U_INT64_MAX,                  INT64_C(60052752001),        INT64_C(60052751999),        INT64_C(5000000),      INT64_C(-9223372036849775808), INT64_C(9223372036849775807)},
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {seconds,      INT64_C(63113904000),        INT64_C(-985451107685),        INT64_C(859223299685),        U_INT64_MIN,                   U_INT64_MAX,                  INT64_C(63113904001),        INT64_C(63113903999),        INT64_C(5000000),      INT64_C(-9223372036849775808), INT64_C(9223372036849775807)},
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {days,         INT64_C(693594),             INT64_C(-11368793),            INT64_C(9981605),             U_INT64_MIN,                   U_INT64_MAX,                  INT64_C(693595),             INT64_C(693593),             INT64_C(432000000000), INT64_C(-9223371604854775808), INT64_C(9223371604854775807)},
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {days,         INT64_C(693594),             INT64_C(-11368793),            INT64_C(9981605),             U_INT64_MIN,                   U_INT64_MAX,                  INT64_C(693595),             INT64_C(693593),             INT64_C(432000000000), INT64_C(-9223371604854775808), INT64_C(9223371604854775807)},
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {microseconds, INT64_C(62135596800000000),  INT64_C(-984472800485477580),  INT64_C(860201606885477580),  INT64_C(-9223372036854775804), INT64_C(9223372036854775804), INT64_C(62135596800000001),  INT64_C(62135596799999999),  INT64_C(5),            INT64_C(-9223372036854775803), INT64_C(9223372036854775802)},
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int64_t U_EXPORT2
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)utmscale_getTimeScaleValue(UDateTimeScale timeScale, UTimeScaleValue value, UErrorCode *status)
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (status == NULL || U_FAILURE(*status)) {
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (timeScale < UDTS_JAVA_TIME || UDTS_MAX_SCALE <= timeScale
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        || value < UTSV_UNITS_VALUE || UTSV_MAX_SCALE_VALUE <= value)
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *status = U_ILLEGAL_ARGUMENT_ERROR;
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return timeScaleTable[timeScale][value];
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int64_t U_EXPORT2
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)utmscale_fromInt64(int64_t otherTime, UDateTimeScale timeScale, UErrorCode *status)
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const int64_t *data;
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (status == NULL || U_FAILURE(*status)) {
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (timeScale < 0 || timeScale >= UDTS_MAX_SCALE) {
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *status = U_ILLEGAL_ARGUMENT_ERROR;
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    data = (const int64_t *)(&timeScaleTable[timeScale]);
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (otherTime < data[UTSV_FROM_MIN_VALUE] || otherTime > data[UTSV_FROM_MAX_VALUE]) {
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *status = U_ILLEGAL_ARGUMENT_ERROR;
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (otherTime + data[UTSV_EPOCH_OFFSET_VALUE]) * data[UTSV_UNITS_VALUE];
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CAPI int64_t U_EXPORT2
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)utmscale_toInt64(int64_t universalTime, UDateTimeScale timeScale, UErrorCode *status)
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const int64_t *data;
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (status == NULL || U_FAILURE(*status)) {
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (timeScale < 0 || timeScale >= UDTS_MAX_SCALE) {
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *status = U_ILLEGAL_ARGUMENT_ERROR;
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    data = (const int64_t *)(&timeScaleTable[timeScale]);
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (universalTime < data[UTSV_TO_MIN_VALUE] || universalTime > data[UTSV_TO_MAX_VALUE]) {
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        *status = U_ILLEGAL_ARGUMENT_ERROR;
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (universalTime < 0) {
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (universalTime < data[UTSV_MIN_ROUND_VALUE]) {
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return (universalTime + data[UTSV_UNITS_ROUND_VALUE]) / data[UTSV_UNITS_VALUE] - data[UTSV_EPOCH_OFFSET_PLUS_1_VALUE];
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return (universalTime - data[UTSV_UNITS_ROUND_VALUE]) / data[UTSV_UNITS_VALUE] - data[UTSV_EPOCH_OFFSET_VALUE];
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (universalTime > data[UTSV_MAX_ROUND_VALUE]) {
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return (universalTime - data[UTSV_UNITS_ROUND_VALUE]) / data[UTSV_UNITS_VALUE] - data[UTSV_EPOCH_OFFSET_MINUS_1_VALUE];
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return (universalTime + data[UTSV_UNITS_ROUND_VALUE]) / data[UTSV_UNITS_VALUE] - data[UTSV_EPOCH_OFFSET_VALUE];
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */
115