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#include "gregoimp.h" 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucal.h" 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uresimp.h" 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h" 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined(U_DEBUG_CALDATA) 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h> 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoint32_t ClockMath::floorDivide(int32_t numerator, int32_t denominator) { 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (numerator >= 0) ? 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru numerator / denominator : ((numerator + 1) / denominator) - 1; 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoint32_t ClockMath::floorDivide(double numerator, int32_t denominator, 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t& remainder) { 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double quotient; 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru quotient = uprv_floor(numerator / denominator); 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru remainder = (int32_t) (numerator - (quotient * denominator)); 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (int32_t) quotient; 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 4085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hodouble ClockMath::floorDivide(double dividend, double divisor, 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double& remainder) { 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Only designed to work for positive divisors 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_ASSERT(divisor > 0); 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double quotient = floorDivide(dividend, divisor); 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru remainder = dividend - (quotient * divisor); 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // N.B. For certain large dividends, on certain platforms, there 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // is a bug such that the quotient is off by one. If you doubt 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // this to be true, set a breakpoint below and run cintltst. 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (remainder < 0 || remainder >= divisor) { 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // E.g. 6.7317038241449352e+022 / 86400000.0 is wrong on my 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // machine (too high by one). 4.1792057231752762e+024 / 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 86400000.0 is wrong the other way (too low). 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double q = quotient; 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru quotient += (remainder < 0) ? -1 : +1; 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (q == quotient) { 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // For quotients > ~2^53, we won't be able to add or 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // subtract one, since the LSB of the mantissa will be > 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 2^0; that is, the exponent (base 2) will be larger than 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the length, in bits, of the mantissa. In that case, we 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // can't give a correct answer, so we set the remainder to 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // zero. This has the desired effect of making extreme 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // values give back an approximate answer rather than 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // crashing. For example, UDate values above a ~10^25 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // might all have a time of midnight. 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru remainder = 0; 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru remainder = dividend - (quotient * divisor); 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru U_ASSERT(0 <= remainder && remainder < divisor); 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return quotient; 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst int32_t JULIAN_1_CE = 1721426; // January 1, 1 CE Gregorian 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst int32_t JULIAN_1970_CE = 2440588; // January 1, 1970 CE Gregorian 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst int16_t Grego::DAYS_BEFORE[24] = 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru {0,31,59,90,120,151,181,212,243,273,304,334, 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0,31,60,91,121,152,182,213,244,274,305,335}; 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst int8_t Grego::MONTH_LENGTH[24] = 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru {31,28,31,30,31,30,31,31,30,31,30,31, 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31,29,31,30,31,30,31,31,30,31,30,31}; 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querudouble Grego::fieldsToDay(int32_t year, int32_t month, int32_t dom) { 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t y = year - 1; 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 8985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho double julian = 365 * y + ClockMath::floorDivide(y, 4) + (JULIAN_1_CE - 3) + // Julian cal 9085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ClockMath::floorDivide(y, 400) - ClockMath::floorDivide(y, 100) + 2 + // => Gregorian cal 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DAYS_BEFORE[month + (isLeapYear(year) ? 12 : 0)] + dom; // => month/dom 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return julian - JULIAN_1970_CE; // JD => epoch day 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid Grego::dayToFields(double day, int32_t& year, int32_t& month, 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t& dom, int32_t& dow, int32_t& doy) { 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Convert from 1970 CE epoch to 1 CE epoch (Gregorian calendar) 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru day += JULIAN_1970_CE - JULIAN_1_CE; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Convert from the day number to the multiple radix 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // representation. We use 400-year, 100-year, and 4-year cycles. 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // For example, the 4-year cycle has 4 years + 1 leap day; giving 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // 1461 == 365*4 + 1 days. 10685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t n400 = ClockMath::floorDivide(day, 146097, doy); // 400-year cycle length 10785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t n100 = ClockMath::floorDivide(doy, 36524, doy); // 100-year cycle length 10885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t n4 = ClockMath::floorDivide(doy, 1461, doy); // 4-year cycle length 10985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t n1 = ClockMath::floorDivide(doy, 365, doy); 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru year = 400*n400 + 100*n100 + 4*n4 + n1; 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (n100 == 4 || n1 == 4) { 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru doy = 365; // Dec 31 at end of 4- or 400-year cycle 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++year; 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool isLeap = isLeapYear(year); 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Gregorian day zero is a Monday. 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dow = (int32_t) uprv_fmod(day + 1, 7); 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dow += (dow < 0) ? (UCAL_SUNDAY + 7) : UCAL_SUNDAY; 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Common Julian/Gregorian calculation 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t correction = 0; 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t march1 = isLeap ? 60 : 59; // zero-based DOY for March 1 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (doy >= march1) { 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru correction = isLeap ? 1 : 2; 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru month = (12 * (doy + correction) + 6) / 367; // zero-based month 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dom = doy - DAYS_BEFORE[month + (isLeap ? 12 : 0)] + 1; // one-based DOM 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru doy++; // one-based doy 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid Grego::timeToFields(UDate time, int32_t& year, int32_t& month, 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t& dom, int32_t& dow, int32_t& doy, int32_t& mid) { 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru double millisInDay; 13785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho double day = ClockMath::floorDivide((double)time, (double)U_MILLIS_PER_DAY, millisInDay); 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mid = (int32_t)millisInDay; 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dayToFields(day, year, month, dom, dow, doy); 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t Grego::dayOfWeek(double day) { 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t dow; 14485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ClockMath::floorDivide(day + UCAL_THURSDAY, 7, dow); 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (dow == 0) ? UCAL_SATURDAY : dow; 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t Grego::dayOfWeekInMonth(int32_t year, int32_t month, int32_t dom) { 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t weekInMonth = (dom + 6)/7; 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (weekInMonth == 4) { 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (dom + 7 > monthLength(year, month)) { 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru weekInMonth = -1; 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (weekInMonth == 5) { 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru weekInMonth = -1; 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return weekInMonth; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* ---- CalendarData ------ */ 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define U_CALENDAR_KEY "calendar" 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define U_GREGORIAN_KEY "gregorian" 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define U_FORMAT_KEY "format" 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define U_DEFAULT_KEY "default" 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define U_CALENDAR_DATA ((char*)0) 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// CalendarData::CalendarData(const Locale& loc, UErrorCode& status) 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// : fFillin(NULL), fBundle(NULL), fFallback(NULL) { 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// initData(loc.getBaseName(), (char*) "???", status); 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// } 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCalendarData::CalendarData(const Locale& loc, const char *type, UErrorCode& status) 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : fFillin(NULL), fOtherFillin(NULL), fBundle(NULL), fFallback(NULL) { 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru initData(loc.getBaseName(), type, status); 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid CalendarData::initData(const char *locale, const char *type, UErrorCode& status) { 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fOtherFillin = ures_open(U_CALENDAR_DATA, locale, &status); 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKey(fOtherFillin, U_CALENDAR_KEY, fFillin, &status); 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if((type != NULL) && 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (*type != '\0') && 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (uprv_strcmp(type, U_GREGORIAN_KEY))) 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fBundle = ures_getByKeyWithFallback(fFillin, type, NULL, &status); 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFallback = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status); 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback(%p, %s)=%s\n", 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this, locale, type, u_errorName(status), fBundle, type, fBundle?ures_getLocale(fBundle, &status):"", 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFallback, U_GREGORIAN_KEY, fFallback?ures_getLocale(fFallback, &status):""); 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fBundle = ures_getByKeyWithFallback(fFillin, U_GREGORIAN_KEY, NULL, &status); 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: CalendarData(%s, %s, %s) -> main(%p, %s)=%s, fallback = NULL\n", 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this, locale, type, u_errorName(status), fBundle, U_GREGORIAN_KEY, fBundle?ures_getLocale(fBundle, &status):"" ); 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCalendarData::~CalendarData() { 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(fFillin); 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(fBundle); 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(fFallback); 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(fOtherFillin); 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUResourceBundle* 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCalendarData::getByKey(const char *key, UErrorCode& status) { 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(status)) { 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fBundle) { 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: get %s -> %s - from MAIN %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status)); 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ZERO_ERROR; // retry with fallback (gregorian) 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: get %s -> %s - from FALLBACK %s\n",this, key, u_errorName(status), ures_getLocale(fFillin, &status)); 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fFillin; 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUResourceBundle* CalendarData::getByKey2(const char *key, const char *subKey, UErrorCode& status) { 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(status)) { 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fBundle) { 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: //\n"); 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status); 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: get %s/format/%s -> %s - from MAIN %s\n", this, key, subKey, u_errorName(status), ures_getLocale(fFillin, &status)); 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ZERO_ERROR; // retry with fallback (gregorian) 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fOtherFillin = ures_getByKeyWithFallback(fFillin, U_FORMAT_KEY, fOtherFillin, &status); 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: get %s/format/%s -> %s - from FALLBACK %s\n",this, key, subKey, u_errorName(status), ures_getLocale(fFillin,&status)); 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//// handling of 'default' keyword on failure: Commented out for 3.0. 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// if((status == U_MISSING_RESOURCE_ERROR) && 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// uprv_strcmp(subKey,U_DEFAULT_KEY)) { // avoid recursion 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// #if defined (U_DEBUG_CALDATA) 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// fprintf(stderr, "%p: - attempting fallback -\n", this); 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// fflush(stderr); 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// #endif 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// UErrorCode subStatus = U_ZERO_ERROR; 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// int32_t len; 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// char kwBuf[128] = ""; 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// const UChar *kw; 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// /* fFillin = */ getByKey2(key, U_DEFAULT_KEY, subStatus); 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// kw = ures_getString(fFillin, &len, &subStatus); 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// if(len>126) { // too big 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// len = 0; 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// } 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// if(U_SUCCESS(subStatus) && (len>0)) { 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// u_UCharsToChars(kw, kwBuf, len+1); 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// if(*kwBuf && uprv_strcmp(kwBuf,subKey)) { 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// #if defined (U_DEBUG_CALDATA) 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// fprintf(stderr, "%p: trying %s/format/default -> \"%s\"\n",this, key, kwBuf); 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// #endif 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// // now try again with the default 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// status = U_ZERO_ERROR; 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// /* fFillin = */ getByKey2(key, kwBuf, status); 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// } 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// #if defined (U_DEBUG_CALDATA) 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// } else { 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// fprintf(stderr, "%p: could not load %s/format/default - fail out (%s)\n",this, key, kwBuf, u_errorName(status)); 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// #endif 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// } 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// } 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fFillin; 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUResourceBundle* CalendarData::getByKey3(const char *key, const char *contextKey, const char *subKey, UErrorCode& status) { 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(status)) { 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fBundle) { 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: //\n"); 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fBundle, key, fFillin, &status); 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status); 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: get %s/%s/%s -> %s - from MAIN %s\n", this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin, &status)); 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(fFallback && (status == U_MISSING_RESOURCE_ERROR)) { 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ZERO_ERROR; // retry with fallback (gregorian) 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fFallback, key, fFillin, &status); 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fOtherFillin = ures_getByKeyWithFallback(fFillin, contextKey, fOtherFillin, &status); 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fFillin = ures_getByKeyWithFallback(fOtherFillin, subKey, fFillin, &status); 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%p: get %s/%s/%s -> %s - from FALLBACK %s\n",this, key, contextKey, subKey, u_errorName(status), ures_getLocale(fFillin,&status)); 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fFillin; 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof 329