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