LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - gregoimp.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 17 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             :  **********************************************************************
       5             :  * Copyright (c) 2003-2008, International Business Machines
       6             :  * Corporation and others.  All Rights Reserved.
       7             :  **********************************************************************
       8             :  * Author: Alan Liu
       9             :  * Created: September 2 2003
      10             :  * Since: ICU 2.8
      11             :  **********************************************************************
      12             :  */
      13             : 
      14             : #ifndef GREGOIMP_H
      15             : #define GREGOIMP_H
      16             : #include "unicode/utypes.h"
      17             : #if !UCONFIG_NO_FORMATTING
      18             : 
      19             : #include "unicode/ures.h"
      20             : #include "unicode/locid.h"
      21             : #include "putilimp.h"
      22             : 
      23             : U_NAMESPACE_BEGIN
      24             : 
      25             : /**
      26             :  * A utility class providing mathematical functions used by time zone
      27             :  * and calendar code.  Do not instantiate.  Formerly just named 'Math'.
      28             :  * @internal
      29             :  */
      30             : class ClockMath {
      31             :  public:
      32             :     /**
      33             :      * Divide two integers, returning the floor of the quotient.
      34             :      * Unlike the built-in division, this is mathematically
      35             :      * well-behaved.  E.g., <code>-1/4</code> => 0 but
      36             :      * <code>floorDivide(-1,4)</code> => -1.
      37             :      * @param numerator the numerator
      38             :      * @param denominator a divisor which must be != 0
      39             :      * @return the floor of the quotient
      40             :      */
      41             :     static int32_t floorDivide(int32_t numerator, int32_t denominator);
      42             : 
      43             :     /**
      44             :      * Divide two numbers, returning the floor of the quotient.
      45             :      * Unlike the built-in division, this is mathematically
      46             :      * well-behaved.  E.g., <code>-1/4</code> => 0 but
      47             :      * <code>floorDivide(-1,4)</code> => -1.
      48             :      * @param numerator the numerator
      49             :      * @param denominator a divisor which must be != 0
      50             :      * @return the floor of the quotient
      51             :      */
      52             :     static inline double floorDivide(double numerator, double denominator);
      53             : 
      54             :     /**
      55             :      * Divide two numbers, returning the floor of the quotient and
      56             :      * the modulus remainder.  Unlike the built-in division, this is
      57             :      * mathematically well-behaved.  E.g., <code>-1/4</code> => 0 and
      58             :      * <code>-1%4</code> => -1, but <code>floorDivide(-1,4)</code> =>
      59             :      * -1 with <code>remainder</code> => 3.  NOTE: If numerator is
      60             :      * too large, the returned quotient may overflow.
      61             :      * @param numerator the numerator
      62             :      * @param denominator a divisor which must be != 0
      63             :      * @param remainder output parameter to receive the
      64             :      * remainder. Unlike <code>numerator % denominator</code>, this
      65             :      * will always be non-negative, in the half-open range <code>[0,
      66             :      * |denominator|)</code>.
      67             :      * @return the floor of the quotient
      68             :      */
      69             :     static int32_t floorDivide(double numerator, int32_t denominator,
      70             :                                int32_t& remainder);
      71             : 
      72             :     /**
      73             :      * For a positive divisor, return the quotient and remainder
      74             :      * such that dividend = quotient*divisor + remainder and
      75             :      * 0 <= remainder < divisor.
      76             :      *
      77             :      * Works around edge-case bugs.  Handles pathological input
      78             :      * (divident >> divisor) reasonably.
      79             :      *
      80             :      * Calling with a divisor <= 0 is disallowed.
      81             :      */
      82             :     static double floorDivide(double dividend, double divisor,
      83             :                               double& remainder);
      84             : };
      85             : 
      86             : // Useful millisecond constants
      87             : #define kOneDay    (1.0 * U_MILLIS_PER_DAY)       //  86,400,000
      88             : #define kOneHour   (60*60*1000)
      89             : #define kOneMinute 60000
      90             : #define kOneSecond 1000
      91             : #define kOneMillisecond  1
      92             : #define kOneWeek   (7.0 * kOneDay) // 604,800,000
      93             : 
      94             : // Epoch constants
      95             : #define kJan1_1JulianDay  1721426 // January 1, year 1 (Gregorian)
      96             : 
      97             : #define kEpochStartAsJulianDay  2440588 // January 1, 1970 (Gregorian)
      98             : 
      99             : #define kEpochYear              1970
     100             : 
     101             : 
     102             : #define kEarliestViableMillis  -185331720384000000.0  // minimum representable by julian day  -1e17
     103             : 
     104             : #define kLatestViableMillis     185753453990400000.0  // max representable by julian day      +1e17
     105             : 
     106             : /**
     107             :  * The minimum supported Julian day.  This value is equivalent to
     108             :  * MIN_MILLIS.
     109             :  */
     110             : #define MIN_JULIAN (-0x7F000000)
     111             : 
     112             : /**
     113             :  * The minimum supported epoch milliseconds.  This value is equivalent
     114             :  * to MIN_JULIAN.
     115             :  */
     116             : #define MIN_MILLIS ((MIN_JULIAN - kEpochStartAsJulianDay) * kOneDay)
     117             : 
     118             : /**
     119             :  * The maximum supported Julian day.  This value is equivalent to
     120             :  * MAX_MILLIS.
     121             :  */
     122             : #define MAX_JULIAN (+0x7F000000)
     123             : 
     124             : /**
     125             :  * The maximum supported epoch milliseconds.  This value is equivalent
     126             :  * to MAX_JULIAN.
     127             :  */
     128             : #define MAX_MILLIS ((MAX_JULIAN - kEpochStartAsJulianDay) * kOneDay)
     129             : 
     130             : /**
     131             :  * A utility class providing proleptic Gregorian calendar functions
     132             :  * used by time zone and calendar code.  Do not instantiate.
     133             :  *
     134             :  * Note:  Unlike GregorianCalendar, all computations performed by this
     135             :  * class occur in the pure proleptic GregorianCalendar.
     136             :  */
     137             : class Grego {
     138             :  public:
     139             :     /**
     140             :      * Return TRUE if the given year is a leap year.
     141             :      * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
     142             :      * @return TRUE if the year is a leap year
     143             :      */
     144             :     static inline UBool isLeapYear(int32_t year);
     145             : 
     146             :     /**
     147             :      * Return the number of days in the given month.
     148             :      * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
     149             :      * @param month 0-based month, with 0==Jan
     150             :      * @return the number of days in the given month
     151             :      */
     152             :     static inline int8_t monthLength(int32_t year, int32_t month);
     153             : 
     154             :     /**
     155             :      * Return the length of a previous month of the Gregorian calendar.
     156             :      * @param y the extended year
     157             :      * @param m the 0-based month number
     158             :      * @return the number of days in the month previous to the given month
     159             :      */
     160             :     static inline int8_t previousMonthLength(int y, int m);
     161             : 
     162             :     /**
     163             :      * Convert a year, month, and day-of-month, given in the proleptic
     164             :      * Gregorian calendar, to 1970 epoch days.
     165             :      * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
     166             :      * @param month 0-based month, with 0==Jan
     167             :      * @param dom 1-based day of month
     168             :      * @return the day number, with day 0 == Jan 1 1970
     169             :      */
     170             :     static double fieldsToDay(int32_t year, int32_t month, int32_t dom);
     171             :     
     172             :     /**
     173             :      * Convert a 1970-epoch day number to proleptic Gregorian year,
     174             :      * month, day-of-month, and day-of-week.
     175             :      * @param day 1970-epoch day (integral value)
     176             :      * @param year output parameter to receive year
     177             :      * @param month output parameter to receive month (0-based, 0==Jan)
     178             :      * @param dom output parameter to receive day-of-month (1-based)
     179             :      * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
     180             :      * @param doy output parameter to receive day-of-year (1-based)
     181             :      */
     182             :     static void dayToFields(double day, int32_t& year, int32_t& month,
     183             :                             int32_t& dom, int32_t& dow, int32_t& doy);
     184             : 
     185             :     /**
     186             :      * Convert a 1970-epoch day number to proleptic Gregorian year,
     187             :      * month, day-of-month, and day-of-week.
     188             :      * @param day 1970-epoch day (integral value)
     189             :      * @param year output parameter to receive year
     190             :      * @param month output parameter to receive month (0-based, 0==Jan)
     191             :      * @param dom output parameter to receive day-of-month (1-based)
     192             :      * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
     193             :      */
     194             :     static inline void dayToFields(double day, int32_t& year, int32_t& month,
     195             :                                    int32_t& dom, int32_t& dow);
     196             : 
     197             :     /**
     198             :      * Convert a 1970-epoch milliseconds to proleptic Gregorian year,
     199             :      * month, day-of-month, and day-of-week, day of year and millis-in-day.
     200             :      * @param time 1970-epoch milliseconds
     201             :      * @param year output parameter to receive year
     202             :      * @param month output parameter to receive month (0-based, 0==Jan)
     203             :      * @param dom output parameter to receive day-of-month (1-based)
     204             :      * @param dow output parameter to receive day-of-week (1-based, 1==Sun)
     205             :      * @param doy output parameter to receive day-of-year (1-based)
     206             :      * @param mid output parameter to recieve millis-in-day
     207             :      */
     208             :     static void timeToFields(UDate time, int32_t& year, int32_t& month,
     209             :                             int32_t& dom, int32_t& dow, int32_t& doy, int32_t& mid);
     210             : 
     211             :     /**
     212             :      * Return the day of week on the 1970-epoch day
     213             :      * @param day the 1970-epoch day (integral value)
     214             :      * @return the day of week
     215             :      */
     216             :     static int32_t dayOfWeek(double day);
     217             : 
     218             :     /**
     219             :      * Returns the ordinal number for the specified day of week within the month.
     220             :      * The valid return value is 1, 2, 3, 4 or -1.
     221             :      * @param year Gregorian year, with 0 == 1 BCE, -1 == 2 BCE, etc.
     222             :      * @param month 0-based month, with 0==Jan
     223             :      * @param dom 1-based day of month
     224             :      * @return The ordinal number for the specified day of week within the month
     225             :      */
     226             :     static int32_t dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom);
     227             : 
     228             :     /**
     229             :      * Converts Julian day to time as milliseconds.
     230             :      * @param julian the given Julian day number.
     231             :      * @return time as milliseconds.
     232             :      * @internal
     233             :      */
     234             :     static inline double julianDayToMillis(int32_t julian);
     235             : 
     236             :     /**
     237             :      * Converts time as milliseconds to Julian day.
     238             :      * @param millis the given milliseconds.
     239             :      * @return the Julian day number.
     240             :      * @internal
     241             :      */
     242             :     static inline int32_t millisToJulianDay(double millis);
     243             : 
     244             :     /** 
     245             :      * Calculates the Gregorian day shift value for an extended year.
     246             :      * @param eyear Extended year 
     247             :      * @returns number of days to ADD to Julian in order to convert from J->G
     248             :      */
     249             :     static inline int32_t gregorianShift(int32_t eyear);
     250             : 
     251             :  private:
     252             :     static const int16_t DAYS_BEFORE[24];
     253             :     static const int8_t MONTH_LENGTH[24];
     254             : };
     255             : 
     256           0 : inline double ClockMath::floorDivide(double numerator, double denominator) {
     257           0 :     return uprv_floor(numerator / denominator);
     258             : }
     259             : 
     260           0 : inline UBool Grego::isLeapYear(int32_t year) {
     261             :     // year&0x3 == year%4
     262           0 :     return ((year&0x3) == 0) && ((year%100 != 0) || (year%400 == 0));
     263             : }
     264             : 
     265             : inline int8_t
     266           0 : Grego::monthLength(int32_t year, int32_t month) {
     267           0 :     return MONTH_LENGTH[month + (isLeapYear(year) ? 12 : 0)];
     268             : }
     269             : 
     270             : inline int8_t
     271           0 : Grego::previousMonthLength(int y, int m) {
     272           0 :   return (m > 0) ? monthLength(y, m-1) : 31;
     273             : }
     274             : 
     275           0 : inline void Grego::dayToFields(double day, int32_t& year, int32_t& month,
     276             :                                int32_t& dom, int32_t& dow) {
     277             :   int32_t doy_unused;
     278           0 :   dayToFields(day,year,month,dom,dow,doy_unused);
     279           0 : }
     280             : 
     281           0 : inline double Grego::julianDayToMillis(int32_t julian)
     282             : {
     283           0 :   return (julian - kEpochStartAsJulianDay) * kOneDay;
     284             : }
     285             : 
     286             : inline int32_t Grego::millisToJulianDay(double millis) {
     287             :   return (int32_t) (kEpochStartAsJulianDay + ClockMath::floorDivide(millis, (double)kOneDay));
     288             : }
     289             : 
     290           0 : inline int32_t Grego::gregorianShift(int32_t eyear) {
     291           0 :   int32_t y = eyear-1;
     292           0 :   int32_t gregShift = ClockMath::floorDivide(y, 400) - ClockMath::floorDivide(y, 100) + 2;
     293           0 :   return gregShift;
     294             : }
     295             : 
     296             : U_NAMESPACE_END
     297             : 
     298             : #endif // !UCONFIG_NO_FORMATTING
     299             : #endif // GREGOIMP_H
     300             : 
     301             : //eof

Generated by: LCOV version 1.13