X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/73c04bcfe1096173b00431f0cdc742894b15eef0..e4f10fab0c078f399c9deef476d9c9b73b47dff8:/icuSources/i18n/gregoimp.cpp diff --git a/icuSources/i18n/gregoimp.cpp b/icuSources/i18n/gregoimp.cpp index 0ebb654f..08a3fbce 100644 --- a/icuSources/i18n/gregoimp.cpp +++ b/icuSources/i18n/gregoimp.cpp @@ -1,13 +1,14 @@ /* -********************************************************************** -* Copyright (c) 2003-2005, International Business Machines -* Corporation and others. All Rights Reserved. -********************************************************************** -* Author: Alan Liu -* Created: September 2 2003 -* Since: ICU 2.8 -********************************************************************** -*/ + ********************************************************************** + * Copyright (c) 2003-2008, International Business Machines + * Corporation and others. All Rights Reserved. + ********************************************************************** + * Author: Alan Liu + * Created: September 2 2003 + * Since: ICU 2.8 + ********************************************************************** + */ + #include "gregoimp.h" #if !UCONFIG_NO_FORMATTING @@ -17,12 +18,18 @@ #include "cstring.h" #include "uassert.h" -int32_t Math::floorDivide(int32_t numerator, int32_t denominator) { +#if defined(U_DEBUG_CALDATA) +#include +#endif + +U_NAMESPACE_BEGIN + +int32_t ClockMath::floorDivide(int32_t numerator, int32_t denominator) { return (numerator >= 0) ? numerator / denominator : ((numerator + 1) / denominator) - 1; } -int32_t Math::floorDivide(double numerator, int32_t denominator, +int32_t ClockMath::floorDivide(double numerator, int32_t denominator, int32_t& remainder) { double quotient; quotient = uprv_floor(numerator / denominator); @@ -30,7 +37,7 @@ int32_t Math::floorDivide(double numerator, int32_t denominator, return (int32_t) quotient; } -double Math::floorDivide(double dividend, double divisor, +double ClockMath::floorDivide(double dividend, double divisor, double& remainder) { // Only designed to work for positive divisors U_ASSERT(divisor > 0); @@ -79,8 +86,8 @@ double Grego::fieldsToDay(int32_t year, int32_t month, int32_t dom) { int32_t y = year - 1; - double julian = 365 * y + Math::floorDivide(y, 4) + (JULIAN_1_CE - 3) + // Julian cal - Math::floorDivide(y, 400) - Math::floorDivide(y, 100) + 2 + // => Gregorian cal + double julian = 365 * y + ClockMath::floorDivide(y, 4) + (JULIAN_1_CE - 3) + // Julian cal + ClockMath::floorDivide(y, 400) - ClockMath::floorDivide(y, 100) + 2 + // => Gregorian cal DAYS_BEFORE[month + (isLeapYear(year) ? 12 : 0)] + dom; // => month/dom return julian - JULIAN_1970_CE; // JD => epoch day @@ -96,10 +103,10 @@ void Grego::dayToFields(double day, int32_t& year, int32_t& month, // representation. We use 400-year, 100-year, and 4-year cycles. // For example, the 4-year cycle has 4 years + 1 leap day; giving // 1461 == 365*4 + 1 days. - int32_t n400 = Math::floorDivide(day, 146097, doy); // 400-year cycle length - int32_t n100 = Math::floorDivide(doy, 36524, doy); // 100-year cycle length - int32_t n4 = Math::floorDivide(doy, 1461, doy); // 4-year cycle length - int32_t n1 = Math::floorDivide(doy, 365, doy); + int32_t n400 = ClockMath::floorDivide(day, 146097, doy); // 400-year cycle length + int32_t n100 = ClockMath::floorDivide(doy, 36524, doy); // 100-year cycle length + int32_t n4 = ClockMath::floorDivide(doy, 1461, doy); // 4-year cycle length + int32_t n1 = ClockMath::floorDivide(doy, 365, doy); year = 400*n400 + 100*n100 + 4*n4 + n1; if (n100 == 4 || n1 == 4) { doy = 365; // Dec 31 at end of 4- or 400-year cycle @@ -124,6 +131,32 @@ void Grego::dayToFields(double day, int32_t& year, int32_t& month, doy++; // one-based doy } +void Grego::timeToFields(UDate time, int32_t& year, int32_t& month, + int32_t& dom, int32_t& dow, int32_t& doy, int32_t& mid) { + double millisInDay; + double day = ClockMath::floorDivide((double)time, (double)U_MILLIS_PER_DAY, millisInDay); + mid = (int32_t)millisInDay; + dayToFields(day, year, month, dom, dow, doy); +} + +int32_t Grego::dayOfWeek(double day) { + int32_t dow; + ClockMath::floorDivide(day + UCAL_THURSDAY, 7, dow); + return (dow == 0) ? UCAL_SATURDAY : dow; +} + +int32_t Grego::dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom) { + int32_t weekInMonth = (dom + 6)/7; + if (weekInMonth == 4) { + if (dom + 7 > monthLength(year, month)) { + weekInMonth = -1; + } + } else if (weekInMonth == 5) { + weekInMonth = -1; + } + return weekInMonth; +} + /* ---- CalendarData ------ */ #define U_CALENDAR_KEY "calendar" @@ -133,10 +166,6 @@ void Grego::dayToFields(double day, int32_t& year, int32_t& month, #define U_CALENDAR_DATA ((char*)0) -#if defined( U_DEBUG_CALDATA) -#include -#endif - // CalendarData::CalendarData(const Locale& loc, UErrorCode& status) // : fFillin(NULL), fBundle(NULL), fFallback(NULL) { // initData(loc.getBaseName(), (char*) "???", status); @@ -293,5 +322,7 @@ UResourceBundle* CalendarData::getByKey3(const char *key, const char *contextKey return fFillin; } +U_NAMESPACE_END + #endif //eof