1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*
2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru **********************************************************************
385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * Copyright (c) 2003-2008, International Business Machines
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Corporation and others.  All Rights Reserved.
5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru **********************************************************************
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Author: Alan Liu
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Created: September 2 2003
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Since: ICU 2.8
9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru **********************************************************************
10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifndef GREGOIMP_H
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define GREGOIMP_H
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h"
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ures.h"
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/locid.h"
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "putilimp.h"
20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN
22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A utility class providing mathematical functions used by time zone
2585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * and calendar code.  Do not instantiate.  Formerly just named 'Math'.
2685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho * @internal
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
2885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoclass ClockMath {
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru public:
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Divide two integers, returning the floor of the quotient.
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Unlike the built-in division, this is mathematically
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * well-behaved.  E.g., <code>-1/4</code> => 0 but
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * <code>floorDivide(-1,4)</code> => -1.
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param numerator the numerator
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param denominator a divisor which must be != 0
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the floor of the quotient
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int32_t floorDivide(int32_t numerator, int32_t denominator);
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Divide two numbers, returning the floor of the quotient.
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Unlike the built-in division, this is mathematically
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * well-behaved.  E.g., <code>-1/4</code> => 0 but
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * <code>floorDivide(-1,4)</code> => -1.
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param numerator the numerator
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param denominator a divisor which must be != 0
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the floor of the quotient
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline double floorDivide(double numerator, double denominator);
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Divide two numbers, returning the floor of the quotient and
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * the modulus remainder.  Unlike the built-in division, this is
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * mathematically well-behaved.  E.g., <code>-1/4</code> => 0 and
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * <code>-1%4</code> => -1, but <code>floorDivide(-1,4)</code> =>
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * -1 with <code>remainder</code> => 3.  NOTE: If numerator is
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * too large, the returned quotient may overflow.
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param numerator the numerator
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param denominator a divisor which must be != 0
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param remainder output parameter to receive the
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * remainder. Unlike <code>numerator % denominator</code>, this
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * will always be non-negative, in the half-open range <code>[0,
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * |denominator|)</code>.
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the floor of the quotient
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int32_t floorDivide(double numerator, int32_t denominator,
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               int32_t& remainder);
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * For a positive divisor, return the quotient and remainder
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * such that dividend = quotient*divisor + remainder and
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * 0 <= remainder < divisor.
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     *
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Works around edge-case bugs.  Handles pathological input
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * (divident >> divisor) reasonably.
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     *
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Calling with a divisor <= 0 is disallowed.
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static double floorDivide(double dividend, double divisor,
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                              double& remainder);
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Useful millisecond constants
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kOneDay    (1.0 * U_MILLIS_PER_DAY)       //  86,400,000
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kOneHour   (60*60*1000)
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kOneMinute 60000
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kOneSecond 1000
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kOneMillisecond  1
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kOneWeek   (7.0 * kOneDay) // 604,800,000
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Epoch constants
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kJan1_1JulianDay  1721426 // January 1, year 1 (Gregorian)
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kEpochStartAsJulianDay  2440588 // January 1, 1970 (Gregorian)
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kEpochYear              1970
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kEarliestViableMillis  -185331720384000000.0  // minimum representable by julian day  -1e17
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kLatestViableMillis     185753453990400000.0  // max representable by julian day      +1e17
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The minimum supported Julian day.  This value is equivalent to
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * MIN_MILLIS.
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MIN_JULIAN (-0x7F000000)
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The minimum supported epoch milliseconds.  This value is equivalent
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to MIN_JULIAN.
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MIN_MILLIS ((MIN_JULIAN - kEpochStartAsJulianDay) * kOneDay)
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The maximum supported Julian day.  This value is equivalent to
118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * MAX_MILLIS.
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAX_JULIAN (+0x7F000000)
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The maximum supported epoch milliseconds.  This value is equivalent
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * to MAX_JULIAN.
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define MAX_MILLIS ((MAX_JULIAN - kEpochStartAsJulianDay) * kOneDay)
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * A utility class providing proleptic Gregorian calendar functions
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * used by time zone and calendar code.  Do not instantiate.
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Note:  Unlike GregorianCalendar, all computations performed by this
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * class occur in the pure proleptic GregorianCalendar.
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass Grego {
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru public:
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Return TRUE if the given year is a leap year.
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return TRUE if the year is a leap year
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline UBool isLeapYear(int32_t year);
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Return the number of days in the given month.
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param month 0-based month, with 0==Jan
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the number of days in the given month
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline int8_t monthLength(int32_t year, int32_t month);
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Return the length of a previous month of the Gregorian calendar.
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param y the extended year
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param m the 0-based month number
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the number of days in the month previous to the given month
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline int8_t previousMonthLength(int y, int m);
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Convert a year, month, and day-of-month, given in the proleptic
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Gregorian calendar, to 1970 epoch days.
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param month 0-based month, with 0==Jan
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dom 1-based day of month
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the day number, with day 0 == Jan 1 1970
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static double fieldsToDay(int32_t year, int32_t month, int32_t dom);
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Convert a 1970-epoch day number to proleptic Gregorian year,
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * month, day-of-month, and day-of-week.
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param day 1970-epoch day (integral value)
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param year output parameter to receive year
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param month output parameter to receive month (0-based, 0==Jan)
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dom output parameter to receive day-of-month (1-based)
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param doy output parameter to receive day-of-year (1-based)
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static void dayToFields(double day, int32_t& year, int32_t& month,
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            int32_t& dom, int32_t& dow, int32_t& doy);
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Convert a 1970-epoch day number to proleptic Gregorian year,
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * month, day-of-month, and day-of-week.
186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param day 1970-epoch day (integral value)
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param year output parameter to receive year
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param month output parameter to receive month (0-based, 0==Jan)
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dom output parameter to receive day-of-month (1-based)
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline void dayToFields(double day, int32_t& year, int32_t& month,
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                                   int32_t& dom, int32_t& dow);
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Convert a 1970-epoch milliseconds to proleptic Gregorian year,
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * month, day-of-month, and day-of-week, day of year and millis-in-day.
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param time 1970-epoch milliseconds
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param year output parameter to receive year
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param month output parameter to receive month (0-based, 0==Jan)
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dom output parameter to receive day-of-month (1-based)
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param doy output parameter to receive day-of-year (1-based)
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param mid output parameter to recieve millis-in-day
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static void timeToFields(UDate time, int32_t& year, int32_t& month,
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            int32_t& dom, int32_t& dow, int32_t& doy, int32_t& mid);
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Return the day of week on the 1970-epoch day
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param day the 1970-epoch day (integral value)
212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the day of week
213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int32_t dayOfWeek(double day);
215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Returns the ordinal number for the specified day of week within the month.
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * The valid return value is 1, 2, 3, 4 or -1.
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param month 0-based month, with 0==Jan
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param dom 1-based day of month
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return The ordinal number for the specified day of week within the month
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static int32_t dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom);
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Converts Julian day to time as milliseconds.
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param julian the given Julian day number.
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return time as milliseconds.
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @internal
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline double julianDayToMillis(int32_t julian);
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Converts time as milliseconds to Julian day.
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param millis the given milliseconds.
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @return the Julian day number.
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @internal
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline int32_t millisToJulianDay(double millis);
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Calculates the Gregorian day shift value for an extended year.
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param eyear Extended year
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @returns number of days to ADD to Julian in order to convert from J->G
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static inline int32_t gregorianShift(int32_t eyear);
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru private:
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int16_t DAYS_BEFORE[24];
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    static const int8_t MONTH_LENGTH[24];
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
25485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoinline double ClockMath::floorDivide(double numerator, double denominator) {
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return uprv_floor(numerator / denominator);
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline UBool Grego::isLeapYear(int32_t year) {
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // year&0x3 == year%4
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return ((year&0x3) == 0) && ((year%100 != 0) || (year%400 == 0));
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline int8_t
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruGrego::monthLength(int32_t year, int32_t month) {
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return MONTH_LENGTH[month + (isLeapYear(year) ? 12 : 0)];
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline int8_t
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruGrego::previousMonthLength(int y, int m) {
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  return (m > 0) ? monthLength(y, m-1) : 31;
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline void Grego::dayToFields(double day, int32_t& year, int32_t& month,
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                               int32_t& dom, int32_t& dow) {
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  int32_t doy_unused;
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  dayToFields(day,year,month,dom,dow,doy_unused);
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline double Grego::julianDayToMillis(int32_t julian)
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  return (julian - kEpochStartAsJulianDay) * kOneDay;
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline int32_t Grego::millisToJulianDay(double millis) {
28585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  return (int32_t) (kEpochStartAsJulianDay + ClockMath::floorDivide(millis, (double)kOneDay));
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruinline int32_t Grego::gregorianShift(int32_t eyear) {
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  int32_t y = eyear-1;
29085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho  int32_t gregShift = ClockMath::floorDivide(y, 400) - ClockMath::floorDivide(y, 100) + 2;
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru  return gregShift;
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * This utility class provides convenient access to the data needed for a calendar.
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @internal ICU 3.0
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass CalendarData : public UMemory {
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic:
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Construct a CalendarData from the given locale.
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param loc locale to use. The 'calendar' keyword will be ignored.
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param type calendar type. NULL indicates the gregorian calendar.
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * No default lookup is done.
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param status error code
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CalendarData(const Locale& loc, const char *type, UErrorCode& status);
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     *
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param key Resource key to data
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param status Error Status
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @internal
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle* getByKey(const char *key, UErrorCode& status);
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * There is an implicit key of 'format'
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * data is located in:   "calendar/key/format/subKey"
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * for example,  calendar/dayNames/format/abbreviated
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     *
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param key Resource key to data
327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param subKey Resource key to data
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param status Error Status
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @internal
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle* getByKey2(const char *key, const char *subKey, UErrorCode& status);
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /**
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * Load data for calendar. Note, this object owns the resources, do NOT call ures_close()!
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * data is located in:   "calendar/key/contextKey/subKey"
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * for example,  calendar/dayNames/standalone/narrow
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * The ResourceBundle C++ API should NOT be used because it is too slow for a low level API.
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     *
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param key Resource key to data
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param contextKey Resource key to data
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param subKey Resource key to data
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @param status Error Status
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     * @internal
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru     */
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle* getByKey3(const char *key, const char *contextKey, const char *subKey, UErrorCode& status);
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ~CalendarData();
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate:
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    void initData(const char *locale, const char *type, UErrorCode& status);
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle *fFillin;
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle *fOtherFillin;
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle *fBundle;
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UResourceBundle *fFallback;
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    CalendarData(); // Not implemented.
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif // !UCONFIG_NO_FORMATTING
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif // GREGOIMP_H
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof
365