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