calendar.cpp revision b13da9df870a61b11249bf741347908dbea0edd8
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Copyright (C) 1997-2007, International Business Machines Corporation and * 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* others. All Rights Reserved. * 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* File CALENDAR.CPP 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification History: 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Description 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/03/97 clhuang Creation. 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 04/22/97 aliu Cleaned up, fixed memory leak, made 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* setWeekCountData() more robust. 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Moved platform code to TPlatformUtilities. 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/01/97 aliu Made equals(), before(), after() arguments const. 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 05/20/97 aliu Changed logic of when to compute fields and time 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* to fix bugs. 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 08/12/97 aliu Added equivalentTo. Misc other fixes. 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 07/28/98 stephen Sync up with JDK 1.2 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 09/02/98 stephen Sync with JDK 1.2 8/31 build (getActualMin/Max) 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/17/99 stephen Changed adoptTimeZone() - now fAreFieldsSet is 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* set to FALSE to force update of time. 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/gregocal.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "gregoimp.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "buddhcal.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "taiwncal.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "japancal.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "islamcal.h" 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "hebrwcal.h" 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "persncal.h" 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "indiancal.h" 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//#include "chnsecal.h" 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/calendar.h" 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cpputils.h" 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "servloc.h" 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucln_in.h" 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "locbased.h" 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresimp.h" 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic U_NAMESPACE_QUALIFIER ICULocaleService* gService = NULL; 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// INTERNAL - for cleanup 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool calendar_cleanup(void) { 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (gService) { 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete gService; 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gService = NULL; 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------------ 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Registration 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------- 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//#define U_DEBUG_CALSVC 1 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL) 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* convert a UCalendarDateFields into a string - for debugging 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @param f field enum 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @return static string to the field name 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @internal 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#error fldName() has been removed. Please use udbg_ucal_fieldName() from libctestfw instead. The following code might work. 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char* fldName(UCalendarDateFields f) { 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *udbg_ucal_fieldName(int32_t fld); 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return udbg_ucal_fieldName((int32_t)f); 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if UCAL_DEBUG_DUMP 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// from CalendarTest::calToStr - but doesn't modify contents. 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid ucal_dump(const Calendar &cal) { 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cal.dump(); 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::dump() const { 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "@calendar=%s, timeset=%c, fieldset=%c, allfields=%c, virtualset=%c, t=%.2f", 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getType(), fIsTimeSet?'y':'n', fAreFieldsSet?'y':'n', fAreAllFieldsSet?'y':'n', 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsVirtuallySet?'y':'n', 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTime); 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // can add more things here: DST, zone, etc. 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "\n"); 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0;i<UCAL_FIELD_COUNT;i++) { 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int n; 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *f = fldName((UCalendarDateFields)i); 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " %25s: %-11ld", f, fFields[i]); 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fStamp[i] == kUnset) { 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " (unset) "); 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(fStamp[i] == kInternallySet) { 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " (internally set) "); 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //} else if(fStamp[i] == kInternalDefault) { 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fprintf(stderr, " (internal default) "); 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " %%%d ", fStamp[i]); 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "\n"); 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CFUNC void ucal_dump(UCalendar* cal) { 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucal_dump( *((Calendar*)cal) ); 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char * const gCalendarKeywords[] = { 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "gregorian", 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "japanese", 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "buddhist", 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "taiwan", 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "persian", 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "islamic-civil", 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "islamic", 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "hebrew", 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "chinese", 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "indian", 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic UBool isStandardSupportedKeyword(const char *keyword, UErrorCode& status) { 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int32_t i=0; gCalendarKeywords[i] != NULL; i++) { 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(uprv_strcmp(gCalendarKeywords[i], keyword) == 0) { 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void getCalendarKeyword(const UnicodeString &id, char *targetBuffer, int32_t targetBufferSize) { 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString calendarKeyword = UNICODE_STRING_SIMPLE("calendar="); 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t calKeyLen = calendarKeyword.length(); 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keyLen = 0; 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordIdx = id.indexOf((UChar)0x003D); /* '=' */ 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (id[0] == 0x40/*'@'*/ 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru && id.compareBetween(1, keywordIdx+1, calendarKeyword, 0, calKeyLen) == 0) 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keyLen = id.extract(keywordIdx+1, id.length(), targetBuffer, targetBufferSize, US_INV); 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru targetBuffer[keyLen] = 0; 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic Calendar *createStandardCalendar(char *calType, const Locale &canLoc, UErrorCode& status) { 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "BasicCalendarFactory %p: creating type for %s\n", 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru this, (const char*)curLoc.getName()); 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fflush(stderr); 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!calType || !*calType || !uprv_strcmp(calType,"gregorian")) { // Gregorian (default) 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new GregorianCalendar(canLoc, status); 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "japanese")) { 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new JapaneseCalendar(canLoc, status); 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "buddhist")) { 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new BuddhistCalendar(canLoc, status); 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "taiwan")) { 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new TaiwanCalendar(canLoc, status); 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "islamic-civil")) { 192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new IslamicCalendar(canLoc, status, IslamicCalendar::CIVIL); 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "islamic")) { 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new IslamicCalendar(canLoc, status, IslamicCalendar::ASTRONOMICAL); 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "hebrew")) { 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new HebrewCalendar(canLoc, status); 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "persian")) { 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new PersianCalendar(canLoc, status); 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //} else if(!uprv_strcmp(calType, "chinese")) { 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //return new ChineseCalendar(canLoc, status); 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(!uprv_strcmp(calType, "indian")) { 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new IndianCalendar(canLoc, status); 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_UNSUPPORTED_ERROR; 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* a Calendar Factory which creates the "basic" calendar types, that is, those 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* shipped with ICU. 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass BasicCalendarFactory : public LocaleKeyFactory { 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /** 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param calendarType static const string (caller owns storage - will be aliased) to calendar type 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BasicCalendarFactory() 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : LocaleKeyFactory(LocaleKeyFactory::INVISIBLE) { } 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual ~BasicCalendarFactory() {} 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprotected: 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //virtual UBool isSupportedID( const UnicodeString& id, UErrorCode& status) const { 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(U_FAILURE(status)) { 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // return FALSE; 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // } 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // char keyword[ULOC_FULLNAME_CAPACITY]; 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // getCalendarKeyword(id, keyword, (int32_t)sizeof(keyword)); 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // return isStandardSupportedKeyword(keyword, status); 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //} 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual void updateVisibleIDs(Hashtable& result, UErrorCode& status) const 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(status)) { 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int32_t i=0;gCalendarKeywords[i] != NULL;i++) { 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString id((UChar)0x40); /* '@' a variant character */ 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru id.append(UNICODE_STRING_SIMPLE("calendar=")); 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru id.append(UnicodeString(gCalendarKeywords[i], -1, US_INV)); 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.put(id, (void*)this, status); 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const { 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(key.getDynamicClassID() != LocaleKey::getStaticClassID()) { 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "::create - not a LocaleKey!\n"); 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const LocaleKey& lkey = (LocaleKey&)key; 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale curLoc; // current locale 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale canLoc; // Canonical locale 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lkey.currentLocale(curLoc); 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lkey.canonicalLocale(canLoc); 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keyword[ULOC_FULLNAME_CAPACITY]; 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString str; 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru key.currentID(str); 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getCalendarKeyword(str, keyword, (int32_t) sizeof(keyword)); 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "BasicCalendarFactory::create() - cur %s, can %s\n", (const char*)curLoc.getName(), (const char*)canLoc.getName()); 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!isStandardSupportedKeyword(keyword,status)) { // Do we handle this type? 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "BasicCalendarFactory - not handling %s.[%s]\n", (const char*) curLoc.getName(), tmp ); 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return createStandardCalendar(keyword, canLoc, status); 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* A factory which looks up the DefaultCalendar resource to determine which class of calendar to use 287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass DefaultCalendarFactory : public ICUResourceBundleFactory { 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DefaultCalendarFactory(): ICUResourceBundleFactory() { } 292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprotected: 293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual UObject* create(const ICUServiceKey& key, const ICUService* /*service*/, UErrorCode& status) const { 294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LocaleKey &lkey = (LocaleKey&)key; 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale loc; 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lkey.currentLocale(loc); 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString myString; 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // attempt keyword lookup 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char keyword[128]; 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!loc.getKeywordValue("calendar", keyword, sizeof(keyword)-1, status)) { 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fetch default calendar id 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char funcEquiv[ULOC_FULLNAME_CAPACITY]; 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_getFunctionalEquivalent(funcEquiv, sizeof(funcEquiv)-1, 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, "calendar", "calendar", 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru loc.getName(), 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, FALSE, &status); 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uloc_getKeywordValue(funcEquiv, "calendar", keyword, 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(keyword)-1, &status); 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " getFunctionalEquivalent calendar=%s [%s]\n", keyword, u_errorName(status)); 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { fprintf(stderr, " explicit calendar=%s\n", keyword); } 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString *ret = new UnicodeString(); 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret->append((UChar)0x40); // '@' is a variant character 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ret->append(UNICODE_STRING("calendar=", 9)); 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (*ret) += UnicodeString(keyword,-1,US_INV); 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ret; 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass CalendarService : public ICULocaleService { 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CalendarService() 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : ICULocaleService(UNICODE_STRING_SIMPLE("Calendar")) 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru registerFactory(new DefaultCalendarFactory(), status); 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual UObject* cloneInstance(UObject* instance) const { 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(instance->getDynamicClassID() == UnicodeString::getStaticClassID()) { 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ((UnicodeString*)instance)->clone(); 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC_F 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status2 = U_ZERO_ERROR; 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "Cloning a %s calendar with tz=%ld\n", ((Calendar*)instance)->getType(), ((Calendar*)instance)->get(UCAL_ZONE_OFFSET, status2)); 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ((Calendar*)instance)->clone(); 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual UObject* handleDefault(const ICUServiceKey& key, UnicodeString* /*actualID*/, UErrorCode& status) const { 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LocaleKey& lkey = (LocaleKey&)key; 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //int32_t kind = lkey.kind(); 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale loc; 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lkey.canonicalLocale(loc); 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale loc2; 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lkey.currentLocale(loc2); 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "CalSvc:handleDefault for currentLoc %s, canloc %s\n", (const char*)loc.getName(), (const char*)loc2.getName()); 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar *nc = new GregorianCalendar(loc, status); 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status2 = U_ZERO_ERROR; 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "New default calendar has tz=%d\n", ((Calendar*)nc)->get(UCAL_ZONE_OFFSET, status2)); 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return nc; 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual UBool isDefault() const { 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return countFactories() == 1; 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic inline UBool 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruisCalendarServiceUsed() { 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool retVal; 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UMTX_CHECK(NULL, gService != NULL, retVal); 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return retVal; 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic ICULocaleService* 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerugetCalendarService(UErrorCode &status) 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool needInit; 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UMTX_CHECK(NULL, (UBool)(gService == NULL), needInit); 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (needInit) { 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "Spinning up Calendar Service\n"); 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ICULocaleService * newservice = new CalendarService(); 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "Registering classes..\n"); 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Register all basic instances. 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newservice->registerFactory(new BasicCalendarFactory(),status); 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "Done..\n"); 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "err (%s) registering classes, deleting service.....\n", u_errorName(status)); 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete newservice; 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newservice = NULL; 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newservice) { 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(NULL); 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (gService == NULL) { 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gService = newservice; 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newservice = NULL; 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(NULL); 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newservice) { 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete newservice; 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we won the contention - we can register the cleanup. 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ucln_i18n_registerCleanup(UCLN_I18N_CALENDAR, calendar_cleanup); 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return gService; 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruURegistryKey Calendar::registerFactory(ICUServiceFactory* toAdopt, UErrorCode& status) 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getCalendarService(status)->registerFactory(toAdopt, status); 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool Calendar::unregister(URegistryKey key, UErrorCode& status) { 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getCalendarService(status)->unregister(key, status); 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* UCONFIG_NO_SERVICE */ 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int32_t kCalendarLimits[UCAL_FIELD_COUNT][4] = { 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Minimum Greatest min Least max Greatest max 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // ERA 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // YEAR 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // MONTH 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // WEEK_OF_YEAR 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // WEEK_OF_MONTH 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // DAY_OF_MONTH 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // DAY_OF_YEAR 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1, 1, 7, 7 }, // DAY_OF_WEEK 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // DAY_OF_WEEK_IN_MONTH 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 1, 1 }, // AM_PM 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 11, 11 }, // HOUR 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 23, 23 }, // HOUR_OF_DAY 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 59, 59 }, // MINUTE 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 59, 59 }, // SECOND 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 999, 999 }, // MILLISECOND 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {-12*kOneHour, -12*kOneHour, 12*kOneHour, 15*kOneHour }, // ZONE_OFFSET 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 1*kOneHour, 1*kOneHour }, // DST_OFFSET 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // YEAR_WOY 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1, 1, 7, 7 }, // DOW_LOCAL 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // EXTENDED_YEAR 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { -0x7F000000, -0x7F000000, 0x7F000000, 0x7F000000 }, // JULIAN_DAY 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 0, 0, 24*kOneHour-1, 24*kOneHour-1 } // MILLISECONDS_IN_DAY 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Resource bundle tags read by this class 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const char gDateTimeElements[] = "DateTimeElements"; 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Data flow in Calendar 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// --------------------- 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// The current time is represented in two ways by Calendar: as UTC 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// millis from the fields, and vice versa. The data needed to do this 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// conversion is encapsulated by a TimeZone object owned by the Calendar. 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// The data provided by the TimeZone object may also be overridden if the 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// keeps track of what information was most recently set by the caller, and 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// uses that to compute any other information as needed. 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// If the user sets the fields using set(), the data flow is as follows. 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// This is implemented by the Calendar subclass's computeTime() method. 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// During this process, certain fields may be ignored. The disambiguation 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// algorithm for resolving which fields to pay attention to is described 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// above. 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | Using Calendar-specific algorithm 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// V 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// local standard millis 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// V 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// UTC millis (in time data member) 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// If the user sets the UTC millis using setTime(), the data flow is as 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// follows. This is implemented by the Calendar subclass's computeFields() 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// method. 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// UTC millis (in time data member) 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | Using TimeZone getOffset() 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// V 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// local standard millis 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// | Using Calendar-specific algorithm 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// V 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.) 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// In general, a round trip from fields, through local and UTC millis, and 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// back out to fields is made when necessary. This is implemented by the 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// complete() method. Resolving a partial set of fields into a UTC millis 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// value allows all remaining fields to be generated from that value. If 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// the Calendar is lenient, the fields are also renormalized to standard 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ranges when they are regenerated. 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::Calendar(UErrorCode& success) 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: UObject(), 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsTimeSet(FALSE), 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreFieldsSet(FALSE), 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreAllFieldsSet(FALSE), 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreFieldsVirtuallySet(FALSE), 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufNextStamp((int32_t)kMinimumUserStamp), 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufTime(0), 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufLenient(TRUE), 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufZone(0) 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clear(); 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fZone = TimeZone::createDefault(); 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setWeekCountData(Locale::getDefault(), NULL, success); 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::Calendar(TimeZone* zone, const Locale& aLocale, UErrorCode& success) 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: UObject(), 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsTimeSet(FALSE), 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreFieldsSet(FALSE), 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreAllFieldsSet(FALSE), 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreFieldsVirtuallySet(FALSE), 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufNextStamp((int32_t)kMinimumUserStamp), 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufTime(0), 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufLenient(TRUE), 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufZone(0) 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(zone == 0) { 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ILLEGAL ARG because timezone cannot be 0\n", 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__); 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = U_ILLEGAL_ARGUMENT_ERROR; 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clear(); 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fZone = zone; 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setWeekCountData(aLocale, NULL, success); 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::Calendar(const TimeZone& zone, const Locale& aLocale, UErrorCode& success) 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: UObject(), 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufIsTimeSet(FALSE), 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreFieldsSet(FALSE), 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreAllFieldsSet(FALSE), 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufAreFieldsVirtuallySet(FALSE), 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufNextStamp((int32_t)kMinimumUserStamp), 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufTime(0), 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufLenient(TRUE), 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerufZone(0) 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clear(); 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fZone = zone.clone(); 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setWeekCountData(aLocale, NULL, success); 593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::~Calendar() 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fZone; 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::Calendar(const Calendar &source) 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru: UObject(source) 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fZone = 0; 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *this = source; 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar & 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::operator=(const Calendar &right) 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (this != &right) { 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_arrayCopy(right.fFields, fFields, UCAL_FIELD_COUNT); 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_arrayCopy(right.fIsSet, fIsSet, UCAL_FIELD_COUNT); 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_arrayCopy(right.fStamp, fStamp, UCAL_FIELD_COUNT); 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTime = right.fTime; 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsTimeSet = right.fIsTimeSet; 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreAllFieldsSet = right.fAreAllFieldsSet; 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsSet = right.fAreFieldsSet; 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsVirtuallySet = right.fAreFieldsVirtuallySet; 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLenient = right.fLenient; 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fZone; 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fZone = right.fZone->clone(); 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstDayOfWeek = right.fFirstDayOfWeek; 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fMinimalDaysInFirstWeek = right.fMinimalDaysInFirstWeek; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fNextStamp = right.fNextStamp; 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar* U_EXPORT2 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::createInstance(UErrorCode& success) 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return createInstance(TimeZone::createDefault(), Locale::getDefault(), success); 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar* U_EXPORT2 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::createInstance(const TimeZone& zone, UErrorCode& success) 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return createInstance(zone, Locale::getDefault(), success); 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar* U_EXPORT2 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::createInstance(const Locale& aLocale, UErrorCode& success) 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return createInstance(TimeZone::createDefault(), aLocale, success); 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- Adopting 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Note: this is the bottleneck that actually calls the service routines. 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar* U_EXPORT2 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& success) 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale actualLoc; 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UObject* u; 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isCalendarServiceUsed()) { 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u = getCalendarService(success)->get(aLocale, LocaleKey::KIND_ANY, &actualLoc, success); 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode feErr; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char calLocaleType[ULOC_FULLNAME_CAPACITY]; 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru calLocaleType[0] = 0; // NULL terminate 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t keywordCapacity = aLocale.getKeywordValue("calendar", calLocaleType, sizeof(calLocaleType)-1, success); 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (keywordCapacity == 0) { 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char funcEquiv[ULOC_FULLNAME_CAPACITY]; 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru feErr = success; 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fetch default calendar id 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_getFunctionalEquivalent(funcEquiv, sizeof(funcEquiv)-1, 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, "calendar", "calendar", 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru aLocale.getName(), 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, FALSE, &feErr); 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keywordCapacity = uloc_getKeywordValue(funcEquiv, "calendar", calLocaleType, 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru sizeof(calLocaleType)-1, &feErr); // This can fail if there is no data. 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Don't want to stop calendar construction just because we couldn't get this type. 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (keywordCapacity == 0 || U_FAILURE(feErr)) { 694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // no calendar type. Default to nothing. 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru calLocaleType[0] = 0; 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " getFunctionalEquivalent calendar=%s [%s]\n", keyword, u_errorName(status)); 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { fprintf(stderr, " explicit calendar=%s\n", keyword); } 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u = createStandardCalendar(calLocaleType, aLocale, success); 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar* c = NULL; 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(success) || !u) { 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete zone; 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(success)) { // Propagate some kind of err 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = U_INTERNAL_PROGRAM_ERROR; 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_SERVICE 717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(u->getDynamicClassID() == UnicodeString::getStaticClassID()) { 718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // It's a unicode string telling us what type of calendar to load ("gregorian", etc) 719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& str = *(UnicodeString*)u; 720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create a Locale over this string 722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale l(""); 723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru LocaleUtility::initLocaleFromName(str, l); 724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "Calendar::createInstance(%s), looking up [%s]\n", aLocale.getName(), l.getName()); 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale actualLoc2; 730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete u; 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru u = NULL; 732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Don't overwrite actualLoc, since the actual loc from this call 734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // may be something like "@calendar=gregorian" -- TODO investigate 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // further... 736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = (Calendar*)getCalendarService(success)->get(l, LocaleKey::KIND_ANY, &actualLoc2, success); 737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(success) || !c) { 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete zone; 740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(success)) { 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = U_INTERNAL_PROGRAM_ERROR; // Propagate some err 742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(c->getDynamicClassID() == UnicodeString::getStaticClassID()) { 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // recursed! Second lookup returned a UnicodeString. 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Perhaps DefaultCalendar{} was set to another locale. 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char tmp[200]; 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString& str = *(UnicodeString*)c; 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Extract a char* out of it.. 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t len = str.length(); 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t actLen = sizeof(tmp)-1; 755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(len > actLen) { 756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru len = actLen; 757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru str.extract(0,len,tmp); 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tmp[len]=0; 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "err - recursed, 2nd lookup was unistring %s\n", tmp); 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru success = U_MISSING_RESOURCE_ERROR; // requested a calendar type which could NOT be found. 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete c; 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete zone; 766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_CALSVC 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%p: setting week count data to locale %s, actual locale %s\n", c, (const char*)aLocale.getName(), (const char *)actualLoc.getName()); 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c->setWeekCountData(aLocale, c->getType(), success); // set the correct locale (this was an indirected calendar) 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* UCONFIG_NO_SERVICE */ 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // a calendar was returned - we assume the factory did the right thing. 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c = (Calendar*)u; 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now, reset calendar to default state: 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c->adoptTimeZone(zone); // Set the correct time zone 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c->setTimeInMillis(getNow(), success); // let the new calendar have the current time. 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return c; 785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar* U_EXPORT2 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode& success) 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar* c = createInstance(aLocale, success); 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(success) && c) { 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru c->setTimeZone(zone); 795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return c; 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::operator==(const Calendar& that) const 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return isEquivalentTo(that) && 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getTimeInMillis(status) == that.getTimeInMillis(status) && 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_SUCCESS(status); 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::isEquivalentTo(const Calendar& other) const 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getDynamicClassID() == other.getDynamicClassID() && 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLenient == other.fLenient && 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstDayOfWeek == other.fFirstDayOfWeek && 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fMinimalDaysInFirstWeek == other.fMinimalDaysInFirstWeek && 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *fZone == *other.fZone; 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::equals(const Calendar& when, UErrorCode& status) const 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (this == &when || 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getTime(status) == when.getTime(status)); 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::before(const Calendar& when, UErrorCode& status) const 833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (this != &when && 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getTimeInMillis(status) < when.getTimeInMillis(status)); 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::after(const Calendar& when, UErrorCode& status) const 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (this != &when && 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getTimeInMillis(status) > when.getTimeInMillis(status)); 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst Locale* U_EXPORT2 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getAvailableLocales(int32_t& count) 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return Locale::getAvailableLocales(count); 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUDate U_EXPORT2 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getNow() 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return uprv_getUTCtime(); // return as milliseconds 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Gets this Calendar's current time as a long. 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @return the current time as UTC milliseconds from the epoch. 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querudouble 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getTimeInMillis(UErrorCode& status) const 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0.0; 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ( ! fIsTimeSet) 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((Calendar*)this)->updateTime(status); 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Test for buffer overflows */ 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0.0; 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fTime; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Sets this Calendar's current time from the given long value. 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @param date the new time in UTC milliseconds from the epoch. 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::setTimeInMillis( double millis, UErrorCode& status ) { 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (millis > MAX_MILLIS) { 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millis = MAX_MILLIS; 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (millis < MIN_MILLIS) { 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millis = MIN_MILLIS; 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTime = millis; 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsSet = fAreAllFieldsSet = FALSE; 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsTimeSet = fAreFieldsVirtuallySet = TRUE; 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::get(UCalendarDateFields field, UErrorCode& status) const 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // field values are only computed when actually requested; for more on when computation 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of various things happens, see the "data flow in Calendar" description at the top 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of this file 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(status)) ((Calendar*)this)->complete(status); // Cast away const 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return U_SUCCESS(status) ? fFields[field] : 0; 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::set(UCalendarDateFields field, int32_t value) 924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAreFieldsVirtuallySet) { 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode ec = U_ZERO_ERROR; 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeFields(ec); 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[field] = value; 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStamp[field] = fNextStamp++; 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsSet[field] = TRUE; // Remove later 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsTimeSet = fAreFieldsSet = fAreFieldsVirtuallySet = FALSE; 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::set(int32_t year, int32_t month, int32_t date) 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_YEAR, year); 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MONTH, month); 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, date); 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute) 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_YEAR, year); 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MONTH, month); 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, date); 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_HOUR_OF_DAY, hour); 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MINUTE, minute); 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t minute, int32_t second) 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_YEAR, year); 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MONTH, month); 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, date); 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_HOUR_OF_DAY, hour); 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MINUTE, minute); 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_SECOND, second); 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::clear() 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t i=0; i<UCAL_FIELD_COUNT; ++i) { 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[i] = 0; // Must do this; other code depends on it 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStamp[i] = kUnset; 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsSet[i] = FALSE; // Remove later 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsTimeSet = fAreFieldsSet = fAreAllFieldsSet = fAreFieldsVirtuallySet = FALSE; 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fTime is not 'cleared' - may be used if no fields are set. 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::clear(UCalendarDateFields field) 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fAreFieldsVirtuallySet) { 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode ec = U_ZERO_ERROR; 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeFields(ec); 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[field] = 0; 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStamp[field] = kUnset; 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsSet[field] = FALSE; // Remove later 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsTimeSet = fAreFieldsSet = fAreAllFieldsSet = fAreFieldsVirtuallySet = FALSE; 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::isSet(UCalendarDateFields field) const 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fAreFieldsVirtuallySet || (fStamp[field] != kUnset); 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::newestStamp(UCalendarDateFields first, UCalendarDateFields last, int32_t bestStampSoFar) const 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t bestStamp = bestStampSoFar; 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t i=(int32_t)first; i<=(int32_t)last; ++i) { 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fStamp[i] > bestStamp) { 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bestStamp = fStamp[i]; 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return bestStamp; 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::complete(UErrorCode& status) 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!fIsTimeSet) { 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru updateTime(status); 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Test for buffer overflows */ 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!fAreFieldsSet) { 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeFields(status); // fills in unset fields 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Test for buffer overflows */ 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsSet = TRUE; 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreAllFieldsSet = TRUE; 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------- 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Protected utility methods for use by subclasses. These are very handy 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// for implementing add, roll, and computeFields. 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------- 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Adjust the specified field so that it is within 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* the allowable range for the date to which this calendar is set. 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH} 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* field for a calendar set to April 31 would cause it to be set 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* to April 30. 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <p> 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <b>Subclassing:</b> 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <br> 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* This utility method is intended for use by subclasses that need to implement 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* their own overrides of {@link #roll roll} and {@link #add add}. 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <p> 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <b>Note:</b> 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <code>pinField</code> is implemented in terms of 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* {@link #getActualMinimum getActualMinimum} 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* and {@link #getActualMaximum getActualMaximum}. If either of those methods uses 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* a slow, iterative algorithm for a particular field, it would be 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* unwise to attempt to call <code>pinField</code> for that field. If you 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* really do need to do so, you should override this method to do 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* something more efficient for that field. 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <p> 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @param field The calendar field whose value should be pinned. 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @see #getActualMinimum 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @see #getActualMaximum 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @stable ICU 2.0 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::pinField(UCalendarDateFields field, UErrorCode& status) { 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t max = getActualMaximum(field, status); 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t min = getActualMinimum(field, status); 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fFields[field] > max) { 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, max); 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (fFields[field] < min) { 1082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, min); 1083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::computeFields(UErrorCode &ec) 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) { 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute local wall millis 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double localMillis = internalGetTime(); 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rawOffset, dstOffset; 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getTimeZone().getOffset(localMillis, FALSE, rawOffset, dstOffset, ec); 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localMillis += (rawOffset + dstOffset); 1097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Mark fields as set. Do this before calling handleComputeFields(). 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t mask = //fInternalSetMask; 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (1 << UCAL_ERA) | 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (1 << UCAL_YEAR) | 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (1 << UCAL_MONTH) | 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (1 << UCAL_DAY_OF_MONTH) | // = UCAL_DATE 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (1 << UCAL_DAY_OF_YEAR) | 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (1 << UCAL_EXTENDED_YEAR); 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t i=0; i<UCAL_FIELD_COUNT; ++i) { 1108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((mask & 1) == 0) { 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStamp[i] = kInternallySet; 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsSet[i] = TRUE; // Remove later 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStamp[i] = kUnset; 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsSet[i] = FALSE; // Remove later 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mask >>= 1; 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We used to check for and correct extreme millis values (near 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Long.MIN_VALUE or Long.MAX_VALUE) here. Such values would cause 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // overflows from positive to negative (or vice versa) and had to 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // be manually tweaked. We no longer need to do this because we 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have limited the range of supported dates to those that have a 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Julian day that fits into an int. This allows us to implement a 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // JULIAN_DAY field and also removes some inelegant code. - Liu 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 11/6/00 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t days = (int32_t)Math::floorDivide(localMillis, (double)kOneDay); 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_JULIAN_DAY,days + kEpochStartAsJulianDay); 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 1132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //fprintf(stderr, "%s:%d- Hmm! Jules @ %d, as per %.0lf millis\n", 1133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //__FILE__, __LINE__, fFields[UCAL_JULIAN_DAY], localMillis); 1134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeGregorianAndDOWFields(fFields[UCAL_JULIAN_DAY], ec); 1137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Call framework method to have subclass compute its fields. 1139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // These must include, at a minimum, MONTH, DAY_OF_MONTH, 1140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // EXTENDED_YEAR, YEAR, DAY_OF_YEAR. This method will call internalSet(), 1141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // which will update stamp[]. 1142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru handleComputeFields(fFields[UCAL_JULIAN_DAY], ec); 1143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute week-related fields, based on the subclass-computed 1145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fields computed by handleComputeFields(). 1146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeWeekFields(ec); 1147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute time-related fields. These are indepent of the date and 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of the subclass algorithm. They depend only on the local zone 1150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // wall milliseconds in day. 1151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t millisInDay = (int32_t) (localMillis - (days * kOneDay)); 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_MILLISECONDS_IN_DAY] = millisInDay; 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_MILLISECOND] = millisInDay % 1000; 1154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay /= 1000; 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_SECOND] = millisInDay % 60; 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay /= 60; 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_MINUTE] = millisInDay % 60; 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay /= 60; 1159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_HOUR_OF_DAY] = millisInDay; 1160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_AM_PM] = millisInDay / 12; // Assume AM == 0 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_HOUR] = millisInDay % 12; 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_ZONE_OFFSET] = rawOffset; 1163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_DST_OFFSET] = dstOffset; 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuint8_t Calendar::julianDayToDayOfWeek(double julian) 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If julian is negative, then julian%7 will be negative, so we adjust 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // accordingly. We add 1 because Julian day 0 is Monday. 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int8_t dayOfWeek = (int8_t) uprv_fmod(julian + 1, 7); 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t result = (uint8_t)(dayOfWeek + ((dayOfWeek < 0) ? (7+UCAL_SUNDAY ) : UCAL_SUNDAY)); 1173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 1174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Compute the Gregorian calendar year, month, and day of month from 1178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* the given Julian day. These values are not stored in fields, but in 1179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* member variables gregorianXxx. Also compute the DAY_OF_WEEK and 1180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DOW_LOCAL fields. 1181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::computeGregorianAndDOWFields(int32_t julianDay, UErrorCode &ec) 1183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeGregorianFields(julianDay, ec); 1185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute day of week: JD 0 = Monday 1187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dow = julianDayToDayOfWeek(julianDay); 1188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_DAY_OF_WEEK,dow); 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Calculate 1-based localized day of week 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dowLocal = dow - getFirstDayOfWeek() + 1; 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dowLocal < 1) { 1193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dowLocal += 7; 1194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_DOW_LOCAL,dowLocal); 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_DOW_LOCAL] = dowLocal; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Compute the Gregorian calendar year, month, and day of month from the 1201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Julian day. These values are not stored in fields, but in member 1202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* variables gregorianXxx. They are used for time zone computations and by 1203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* subclasses that are Gregorian derivatives. Subclasses may call this 1204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* method to perform a Gregorian calendar millis->fields computation. 1205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* To perform a Gregorian calendar fields->millis computation, call 1206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* computeGregorianMonthStart(). 1207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @see #computeGregorianMonthStart 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::computeGregorianFields(int32_t julianDay, UErrorCode & /* ec */) { 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gregorianDayOfWeekUnused; 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Grego::dayToFields(julianDay - kEpochStartAsJulianDay, fGregorianYear, fGregorianMonth, fGregorianDayOfMonth, gregorianDayOfWeekUnused, fGregorianDayOfYear); 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH, 1216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR, 1217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DAY_OF_WEEK, and DAY_OF_YEAR. The latter fields are computed by the 1218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* subclass based on the calendar system. 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <p>The YEAR_WOY field is computed simplistically. It is equal to YEAR 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* most of the time, but at the year boundary it may be adjusted to YEAR-1 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* or YEAR+1 to reflect the overlap of a week into an adjacent year. In 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* this case, a simple increment or decrement is performed on YEAR, even 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* though this may yield an invalid YEAR value. For instance, if the YEAR 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* is part of a calendar system with an N-year cycle field CYCLE, then 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* incrementing the YEAR may involve incrementing CYCLE and setting YEAR 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* back to 0 or 1. This is not handled by this code, and in fact cannot be 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* simply handled without having subclasses define an entire parallel set of 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* fields for fields larger than or equal to a year. This additional 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* complexity is not warranted, since the intention of the YEAR_WOY field is 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* to support ISO 8601 notation, so it will typically be used with a 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* proleptic Gregorian calendar, which has no field larger than a year. 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::computeWeekFields(UErrorCode &ec) { 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(ec)) { 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t eyear = fFields[UCAL_EXTENDED_YEAR]; 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t year = fFields[UCAL_YEAR]; 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dayOfWeek = fFields[UCAL_DAY_OF_WEEK]; 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dayOfYear = fFields[UCAL_DAY_OF_YEAR]; 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // WEEK_OF_YEAR start 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute the week of the year. For the Gregorian calendar, valid week 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // numbers run from 1 to 52 or 53, depending on the year, the first day 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of the week, and the minimal days in the first week. For other 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // calendars, the valid range may be different -- it depends on the year 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // length. Days at the start of the year may fall into the last week of 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the previous year; days at the end of the year may fall into the 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // first week of the next year. ASSUME that the year length is less than 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 7000 days. 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t yearOfWeekOfYear = year; 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) { 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++woy; 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Adjust for weeks at the year end that overlap into the previous or 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // next calendar year. 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (woy == 0) { 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We are the last week of the previous year. 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Check to see if we are in the last week; if so, we need 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to handle the case in which we are the first week of the 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // next year. 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t prevDoy = dayOfYear + handleGetYearLength(eyear - 1); 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru woy = weekNumber(prevDoy, dayOfWeek); 1270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru yearOfWeekOfYear--; 1271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lastDoy = handleGetYearLength(eyear); 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Fast check: For it to be week 1 of the next year, the DOY 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // must be on or after L-5, where L is yearLength(), then it 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // cannot possibly be week 1 of the next year: 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // L-5 L 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // doy: 359 360 361 362 363 364 365 001 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // dow: 1 2 3 4 5 6 7 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dayOfYear >= (lastDoy - 5)) { 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lastRelDow = (relDow + lastDoy - dayOfYear) % 7; 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lastRelDow < 0) { 1282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lastRelDow += 7; 1283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) && 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ((dayOfYear + 7 - relDow) > lastDoy)) { 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru woy = 1; 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru yearOfWeekOfYear++; 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_WEEK_OF_YEAR] = woy; 1292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_YEAR_WOY] = yearOfWeekOfYear; 1293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // WEEK_OF_YEAR end 1294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dayOfMonth = fFields[UCAL_DAY_OF_MONTH]; 1296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek); 1297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFields[UCAL_DAY_OF_WEEK_IN_MONTH] = (dayOfMonth-1) / 7 + 1; 1298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 1299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(fFields[UCAL_DAY_OF_WEEK_IN_MONTH]==0) fprintf(stderr, "%s:%d: DOWIM %d on %g\n", 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,fFields[UCAL_DAY_OF_WEEK_IN_MONTH], fTime); 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::weekNumber(int32_t desiredDay, int32_t dayOfPeriod, int32_t dayOfWeek) 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Determine the day of the week of the first day of the period 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in question (either a year or a month). Zero represents the 1309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // first day of the week on this calendar. 1310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % 7; 1311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (periodStartDayOfWeek < 0) periodStartDayOfWeek += 7; 1312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute the week number. Initially, ignore the first week, which 1314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // may be fractional (or may not be). We add periodStartDayOfWeek in 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // order to fill out the first week, if it is fractional. 1316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t weekNo = (desiredDay + periodStartDayOfWeek - 1)/7; 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the first week is long enough, then count it. If 1319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the minimal days in the first week is one, or if the period start 1320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is zero, we always increment weekNo. 1321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) ++weekNo; 1322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return weekNo; 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::handleComputeFields(int32_t /* julianDay */, UErrorCode &/* status */) 1327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_MONTH, getGregorianMonth()); 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_DAY_OF_MONTH, getGregorianDayOfMonth()); 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_DAY_OF_YEAR, getGregorianDayOfYear()); 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t eyear = getGregorianYear(); 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_EXTENDED_YEAR, eyear); 1333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t era = GregorianCalendar::AD; 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (eyear < 1) { 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru era = GregorianCalendar::BC; 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru eyear = 1 - eyear; 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_ERA, era); 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_YEAR, eyear); 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::roll(EDateFields field, int32_t amount, UErrorCode& status) 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru roll((UCalendarDateFields)field, amount, status); 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& status) 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (amount == 0) { 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // Nothing to do 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru complete(status); 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_MONTH: 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_AM_PM: 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MINUTE: 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_SECOND: 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECOND: 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECONDS_IN_DAY: 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_ERA: 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // These are the standard roll instructions. These work for all 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // simple cases, that is, cases in which the limits are fixed, such 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // as the hour, the day of the month, and the era. 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t min = getActualMinimum(field,status); 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t max = getActualMaximum(field,status); 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gap = max - min + 1; 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t value = internalGet(field) + amount; 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = (value - min) % gap; 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (value < 0) { 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value += gap; 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value += min; 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, value); 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR: 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR_OF_DAY: 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Rolling the hour is difficult on the ONSET and CEASE days of 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // daylight savings. For example, if the change occurs at 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 2 AM, we have the following progression: 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // To get around this problem we don't use fields; we manipulate 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the time in millis directly. 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Assume min == 0 in calculations below 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double start = getTimeInMillis(status); 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t oldHour = internalGet(field); 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t max = getMaximum(field); 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t newHour = (oldHour + amount) % (max + 1); 1402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newHour < 0) { 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newHour += max + 1; 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(start + kOneHour * (newHour - oldHour),status); 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MONTH: 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Rolling the month involves both pinning the final value 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // and adjusting the DAY_OF_MONTH if necessary. We only adjust the 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // DAY_OF_MONTH if, after updating the MONTH field, it is illegal. 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>. 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t max = getActualMaximum(UCAL_MONTH, status); 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t mon = (internalGet(UCAL_MONTH) + amount) % (max+1); 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (mon < 0) { 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru mon += (max + 1); 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MONTH, mon); 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Keep the day of month in range. We don't want to spill over 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 -> 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // mar3. 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinField(UCAL_DAY_OF_MONTH,status); 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR: 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR_WOY: 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_EXTENDED_YEAR: 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Rolling the year can involve pinning the DAY_OF_MONTH. 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, internalGet(field) + amount); 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinField(UCAL_MONTH,status); 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinField(UCAL_DAY_OF_MONTH,status); 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_MONTH: 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This is tricky, because during the roll we may have to shift 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to a different day of the week. For example: 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // s m t w r f s 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1 2 3 4 5 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 6 7 8 9 10 11 12 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // When rolling from the 6th or 7th back one week, we go to the 1449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1st (assuming that the first partial week counts). The same 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // thing happens at the end of the month. 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The other tricky thing is that we have to figure out whether 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the first partial week actually counts or not, based on the 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // minimal first days in the week. And we have to use the 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // correct first day of the week to delineate the week 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // boundaries. 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Here's our algorithm. First, we find the real boundaries of 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the month. Then we discard the first partial week if it 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // doesn't count in this locale. Then we fill in the ends with 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // phantom days, so that the first partial week and the last 1462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // partial week are full weeks. We then have a nice square 1463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // block of weeks. We do the usual rolling within this block, 1464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // as is done elsewhere in this method. If we wind up on one of 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the phantom days that we added, we recognize this and pin to 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the first or the last day of the month. Easy, eh? 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Normalize the DAY_OF_WEEK so that 0 is the first day of the week 1469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in this locale. We have dow in 0..6. 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek(); 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dow < 0) dow += 7; 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the day of the week (normalized for locale) for the first 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of the month. 1475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t fdm = (dow - internalGet(UCAL_DAY_OF_MONTH) + 1) % 7; 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fdm < 0) fdm += 7; 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the first day of the first full week of the month, 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // including phantom days, if any. Figure out if the first week 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // counts or not; if it counts, then fill in phantom days. If 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // not, advance to the first real full week (skip the partial week). 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start; 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((7 - fdm) < getMinimalDaysInFirstWeek()) 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = 8 - fdm; // Skip the first partial week 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = 1 - fdm; // This may be zero or negative 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the day of the week (normalized for locale) for the last 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // day of the month. 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t monthLen = getActualMaximum(UCAL_DAY_OF_MONTH, status); 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t ldm = (monthLen - internalGet(UCAL_DAY_OF_MONTH) + dow) % 7; 1492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here. 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the limit day for the blocked-off rectangular month; that 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is, the day which is one past the last day of the month, 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // after the month has already been filled in with phantom days 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to fill out the last week. This day has a normalized DOW of 0. 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit = monthLen + 7 - ldm; 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now roll between start and (limit - 1). 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gap = limit - start; 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t day_of_month = (internalGet(UCAL_DAY_OF_MONTH) + amount*7 - 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start) % gap; 1504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (day_of_month < 0) day_of_month += gap; 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru day_of_month += start; 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Finally, pin to the real start and end of the month. 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (day_of_month < 1) day_of_month = 1; 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (day_of_month > monthLen) day_of_month = monthLen; 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set the DAY_OF_MONTH. We rely on the fact that this field 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // takes precedence over everything else (since all other fields 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // are also set at this point). If this fact changes (if the 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // disambiguation algorithm changes) then we will have to unset 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the appropriate fields here so that DAY_OF_MONTH is attended 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to. 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DAY_OF_MONTH, day_of_month); 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_YEAR: 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This follows the outline of WEEK_OF_MONTH, except it applies 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to the whole year. Please see the comment for WEEK_OF_MONTH 1524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // for general notes. 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Normalize the DAY_OF_WEEK so that 0 is the first day of the week 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in this locale. We have dow in 0..6. 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dow = internalGet(UCAL_DAY_OF_WEEK) - getFirstDayOfWeek(); 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dow < 0) dow += 7; 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the day of the week (normalized for locale) for the first 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of the year. 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t fdy = (dow - internalGet(UCAL_DAY_OF_YEAR) + 1) % 7; 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fdy < 0) fdy += 7; 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the first day of the first full week of the year, 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // including phantom days, if any. Figure out if the first week 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // counts or not; if it counts, then fill in phantom days. If 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // not, advance to the first real full week (skip the partial week). 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t start; 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((7 - fdy) < getMinimalDaysInFirstWeek()) 1542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = 8 - fdy; // Skip the first partial week 1543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 1544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start = 1 - fdy; // This may be zero or negative 1545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the day of the week (normalized for locale) for the last 1547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // day of the year. 1548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t yearLen = getActualMaximum(UCAL_DAY_OF_YEAR,status); 1549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t ldy = (yearLen - internalGet(UCAL_DAY_OF_YEAR) + dow) % 7; 1550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here. 1551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the limit day for the blocked-off rectangular year; that 1553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is, the day which is one past the last day of the year, 1554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // after the year has already been filled in with phantom days 1555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to fill out the last week. This day has a normalized DOW of 0. 1556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t limit = yearLen + 7 - ldy; 1557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now roll between start and (limit - 1). 1559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t gap = limit - start; 1560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t day_of_year = (internalGet(UCAL_DAY_OF_YEAR) + amount*7 - 1561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru start) % gap; 1562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (day_of_year < 0) day_of_year += gap; 1563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru day_of_year += start; 1564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Finally, pin to the real start and end of the month. 1566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (day_of_year < 1) day_of_year = 1; 1567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (day_of_year > yearLen) day_of_year = yearLen; 1568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Make sure that the year and day of year are attended to by 1570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clearing other fields which would normally take precedence. 1571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the disambiguation algorithm is changed, this section will 1572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have to be updated as well. 1573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DAY_OF_YEAR, day_of_year); 1574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clear(UCAL_MONTH); 1575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_YEAR: 1578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Roll the day of year using millis. Compute the millis for 1580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the start of the year, and get the length of the year. 1581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double delta = amount * kOneDay; // Scale up from days to millis 1582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double min2 = internalGet(UCAL_DAY_OF_YEAR)-1; 1583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min2 *= kOneDay; 1584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min2 = internalGetTime() - min2; 1585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // double min2 = internalGetTime() - (internalGet(UCAL_DAY_OF_YEAR) - 1.0) * kOneDay; 1587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double newtime; 1588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double yearLength = getActualMaximum(UCAL_DAY_OF_YEAR,status); 1590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double oneYear = yearLength; 1591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oneYear *= kOneDay; 1592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newtime = uprv_fmod((internalGetTime() + delta - min2), oneYear); 1593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newtime < 0) newtime += oneYear; 1594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(newtime + min2, status); 1595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK: 1598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DOW_LOCAL: 1599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Roll the day of week using millis. Compute the millis for 1601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the start of the week, using the first day of week setting. 1602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Restrict the millis to [start, start+7days). 1603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double delta = amount * kOneDay; // Scale up from days to millis 1604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute the number of days before the current day in this 1605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // week. This will be a value 0..6. 1606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t leadDays = internalGet(field); 1607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru leadDays -= (field == UCAL_DAY_OF_WEEK) ? getFirstDayOfWeek() : 1; 1608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (leadDays < 0) leadDays += 7; 1609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double min2 = internalGetTime() - leadDays * kOneDay; 1610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double newtime = uprv_fmod((internalGetTime() + delta - min2), kOneWeek); 1611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newtime < 0) newtime += kOneWeek; 1612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(newtime + min2, status); 1613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK_IN_MONTH: 1616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Roll the day of week in the month using millis. Determine 1618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the first day of the week in the month, and then the last, 1619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // and then roll within that range. 1620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double delta = amount * kOneWeek; // Scale up from weeks to millis 1621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the number of same days of the week before this one 1622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in this month. 1623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t preWeeks = (internalGet(UCAL_DAY_OF_MONTH) - 1) / 7; 1624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the number of same days of the week after this one 1625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in this month. 1626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t postWeeks = (getActualMaximum(UCAL_DAY_OF_MONTH,status) - 1627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalGet(UCAL_DAY_OF_MONTH)) / 7; 1628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // From these compute the min and gap millis for rolling. 1629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double min2 = internalGetTime() - preWeeks * kOneWeek; 1630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double gap2 = kOneWeek * (preWeeks + postWeeks + 1); // Must add 1! 1631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Roll within this range 1632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double newtime = uprv_fmod((internalGetTime() + delta - min2), gap2); 1633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (newtime < 0) newtime += gap2; 1634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(newtime + min2, status); 1635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_JULIAN_DAY: 1638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, internalGet(field) + amount); 1639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Other fields cannot be rolled by this method 1642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 1643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ILLEGAL ARG because of roll on non-rollable field %s\n", 1644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,fldName(field)); 1645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::add(EDateFields field, int32_t amount, UErrorCode& status) 1651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar::add((UCalendarDateFields)field, amount, status); 1653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status) 1657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (amount == 0) { 1659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // Do nothing! 1660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We handle most fields in the same way. The algorithm is to add 1663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // a computed amount of millis to the current millis. The only 1664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // wrinkle is with DST -- for some fields, like the DAY_OF_MONTH, 1665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we don't want the HOUR to shift due to changes in DST. If the 1666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // result of the add operation is to move from DST to Standard, or 1667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // vice versa, we need to adjust by an hour forward or back, 1668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // respectively. For such fields we set keepHourInvariant to TRUE. 1669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We only adjust the DST for fields larger than an hour. For 1671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fields smaller than an hour, we cannot adjust for DST without 1672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // causing problems. for instance, if you add one hour to April 5, 1673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an 1674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // illegal value), but then the adjustment sees the change and 1675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compensates by subtracting an hour. As a result the time 1676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // doesn't advance at all. 1677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // For some fields larger than a day, such as a UCAL_MONTH, we pin the 1679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // UCAL_DAY_OF_MONTH. This allows <March 31>.add(UCAL_MONTH, 1) to be 1680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // <April 30>, rather than <April 31> => <May 1>. 1681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double delta = amount; // delta in ms 1683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool keepHourInvariant = TRUE; 1684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 1686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_ERA: 1687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, get(field, status) + amount); 1688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinField(UCAL_ERA, status); 1689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR: 1692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_EXTENDED_YEAR: 1693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR_WOY: 1694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MONTH: 1695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, get(field, status) + amount); 1696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru pinField(UCAL_DAY_OF_MONTH, status); 1697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_YEAR: 1700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_MONTH: 1701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK_IN_MONTH: 1702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta *= kOneWeek; 1703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_AM_PM: 1706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta *= 12 * kOneHour; 1707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_MONTH: 1710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_YEAR: 1711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK: 1712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DOW_LOCAL: 1713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_JULIAN_DAY: 1714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta *= kOneDay; 1715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR_OF_DAY: 1718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR: 1719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta *= kOneHour; 1720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keepHourInvariant = FALSE; 1721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MINUTE: 1724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta *= kOneMinute; 1725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keepHourInvariant = FALSE; 1726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_SECOND: 1729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delta *= kOneSecond; 1730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keepHourInvariant = FALSE; 1731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECOND: 1734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECONDS_IN_DAY: 1735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru keepHourInvariant = FALSE; 1736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 1739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 1740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s not addable", 1741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, fldName(field)); 1742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // throw new IllegalArgumentException("Calendar.add(" + fieldName(field) + 1746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // ") not supported"); 1747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // In order to keep the hour invariant (for fields where this is 1750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // appropriate), record the DST_OFFSET before and after the add() 1751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // operation. If it has changed, then adjust the millis to 1752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // compensate. 1753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dst = 0; 1754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t hour = 0; 1755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (keepHourInvariant) { 1756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dst = get(UCAL_DST_OFFSET, status); 1757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hour = internalGet(UCAL_HOUR_OF_DAY); 1758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(getTimeInMillis(status) + delta, status); 1761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (keepHourInvariant) { 1763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dst -= get(UCAL_DST_OFFSET, status); 1764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dst != 0) { 1765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We have done an hour-invariant adjustment but the 1766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // DST offset has altered. We adjust millis to keep 1767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the hour constant. In cases such as midnight after 1768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // a DST change which occurs at midnight, there is the 1769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // danger of adjusting into a different day. To avoid 1770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // this we make the adjustment only if it actually 1771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // maintains the hour. 1772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double t = internalGetTime(); 1773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(t + dst, status); 1774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (get(UCAL_HOUR_OF_DAY, status) != hour) { 1775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(t, status); 1776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::fieldDifference(UDate when, EDateFields field, UErrorCode& status) { 1783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fieldDifference(when, (UCalendarDateFields) field, status); 1784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::fieldDifference(UDate targetMs, UCalendarDateFields field, UErrorCode& ec) { 1787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) return 0; 1788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t min = 0; 1789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double startMs = getTimeInMillis(ec); 1790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Always add from the start millis. This accomodates 1791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // operations like adding years from February 29, 2000 up to 1792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // February 29, 2004. If 1, 1, 1, 1 is added to the year 1793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // field, the DOM gets pinned to 28 and stays there, giving an 1794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // incorrect DOM difference of 1. We have to add 1, reset, 2, 1795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // reset, 3, reset, 4. 1796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (startMs < targetMs) { 1797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t max = 1; 1798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find a value that is too large 1799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (U_SUCCESS(ec)) { 1800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(startMs, ec); 1801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru add(field, max, ec); 1802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double ms = getTimeInMillis(ec); 1803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ms == targetMs) { 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return max; 1805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (ms > targetMs) { 1806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max <<= 1; 1809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (max < 0) { 1810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Field difference too large to fit into int32_t 1811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 1812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s's max too large for int32_t\n", 1813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, fldName(field)); 1814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 1816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Do a binary search 1820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((max - min) > 1 && U_SUCCESS(ec)) { 1821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t t = (min + max) / 2; 1822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(startMs, ec); 1823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru add(field, t, ec); 1824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double ms = getTimeInMillis(ec); 1825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ms == targetMs) { 1826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return t; 1827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (ms > targetMs) { 1828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max = t; 1829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min = t; 1831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (startMs > targetMs) { 1834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t max = -1; 1835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find a value that is too small 1836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (U_SUCCESS(ec)) { 1837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(startMs, ec); 1838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru add(field, max, ec); 1839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double ms = getTimeInMillis(ec); 1840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ms == targetMs) { 1841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return max; 1842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (ms < targetMs) { 1843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max <<= 1; 1846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (max == 0) { 1847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Field difference too large to fit into int32_t 1848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 1849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ILLEGAL ARG because field %s's max too large for int32_t\n", 1850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, fldName(field)); 1851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 1852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 1853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Do a binary search 1857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while ((min - max) > 1 && U_SUCCESS(ec)) { 1858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t t = (min + max) / 2; 1859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(startMs, ec); 1860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru add(field, t, ec); 1861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double ms = getTimeInMillis(ec); 1862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ms == targetMs) { 1863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return t; 1864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (ms < targetMs) { 1865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru max = t; 1866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru min = t; 1868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set calendar to end point 1872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru setTimeInMillis(startMs, ec); 1873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru add(field, min, ec); 1874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Test for buffer overflows */ 1876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(ec)) { 1877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return min; 1880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::adoptTimeZone(TimeZone* zone) 1886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Do nothing if passed-in zone is NULL 1888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (zone == NULL) return; 1889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fZone should always be non-null 1891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fZone != NULL) delete fZone; 1892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fZone = zone; 1893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if the zone changes, we need to recompute the time fields 1895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsSet = FALSE; 1896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::setTimeZone(const TimeZone& zone) 1901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru adoptTimeZone(zone.clone()); 1903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst TimeZone& 1908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getTimeZone() const 1909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *fZone; 1911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZone* 1916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::orphanTimeZone() 1917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TimeZone *z = fZone; 1919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we let go of the time zone; the new time zone is the system default time zone 1920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fZone = TimeZone::createDefault(); 1921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return z; 1922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::setLenient(UBool lenient) 1928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fLenient = lenient; 1930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 1935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::isLenient() const 1936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fLenient; 1938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::setFirstDayOfWeek(UCalendarDaysOfWeek value) 1944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fFirstDayOfWeek != value && 1946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value >= UCAL_SUNDAY && value <= UCAL_SATURDAY) { 1947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstDayOfWeek = value; 1948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsSet = FALSE; 1949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::EDaysOfWeek 1955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getFirstDayOfWeek() const 1956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (Calendar::EDaysOfWeek)fFirstDayOfWeek; 1958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUCalendarDaysOfWeek 1961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getFirstDayOfWeek(UErrorCode & /*status*/) const 1962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fFirstDayOfWeek; 1964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::setMinimalDaysInFirstWeek(uint8_t value) 1969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Values less than 1 have the same effect as 1; values greater 1971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // than 7 have the same effect as 7. However, we normalize values 1972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // so operator== and so forth work. 1973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (value < 1) { 1974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = 1; 1975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (value > 7) { 1976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru value = 7; 1977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fMinimalDaysInFirstWeek != value) { 1979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fMinimalDaysInFirstWeek = value; 1980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsSet = FALSE; 1981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 1985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruuint8_t 1987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getMinimalDaysInFirstWeek() const 1988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fMinimalDaysInFirstWeek; 1990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- limits 1993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 1995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getMinimum(EDateFields field) const { 1996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MINIMUM); 1997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getMinimum(UCalendarDateFields field) const 2001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit(field,UCAL_LIMIT_MINIMUM); 2003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 2006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getMaximum(EDateFields field) const 2008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit((UCalendarDateFields) field,UCAL_LIMIT_MAXIMUM); 2010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getMaximum(UCalendarDateFields field) const 2014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit(field,UCAL_LIMIT_MAXIMUM); 2016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 2019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getGreatestMinimum(EDateFields field) const 2021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit((UCalendarDateFields)field,UCAL_LIMIT_GREATEST_MINIMUM); 2023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getGreatestMinimum(UCalendarDateFields field) const 2027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit(field,UCAL_LIMIT_GREATEST_MINIMUM); 2029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 2032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getLeastMaximum(EDateFields field) const 2034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit((UCalendarDateFields) field,UCAL_LIMIT_LEAST_MAXIMUM); 2036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getLeastMaximum(UCalendarDateFields field) const 2040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getLimit( field,UCAL_LIMIT_LEAST_MAXIMUM); 2042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 2045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getActualMinimum(EDateFields field, UErrorCode& status) const 2047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getActualMinimum((UCalendarDateFields) field, status); 2049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::getLimit(UCalendarDateFields field, ELimitType limitType) const { 2052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 2053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK: 2054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_AM_PM: 2055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR: 2056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR_OF_DAY: 2057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MINUTE: 2058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_SECOND: 2059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECOND: 2060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_ZONE_OFFSET: 2061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DST_OFFSET: 2062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DOW_LOCAL: 2063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_JULIAN_DAY: 2064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECONDS_IN_DAY: 2065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return kCalendarLimits[field][limitType]; 2066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 2067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return handleGetLimit(field, limitType); 2068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getActualMinimum(UCalendarDateFields field, UErrorCode& status) const 2074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t fieldValue = getGreatestMinimum(field); 2076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t endValue = getMinimum(field); 2077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if we know that the minimum value is always the same, just return it 2079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fieldValue == endValue) { 2080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return fieldValue; 2081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2082b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2083b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clone the calendar so we don't mess with the real one, and set it to 2084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // accept anything for the field values 2085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar *work = (Calendar*)this->clone(); 2086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru work->setLenient(TRUE); 2087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now try each value from getLeastMaximum() to getMaximum() one by one until 2089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we get a value that normalizes to another value. The last value that 2090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // normalizes to itself is the actual minimum for the current date 2091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result = fieldValue; 2092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 2094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru work->set(field, fieldValue); 2095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (work->get(field, status) != fieldValue) { 2096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2097b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 2099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = fieldValue; 2100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fieldValue--; 2101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (fieldValue >= endValue); 2103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete work; 2105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Test for buffer overflows */ 2107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 2108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 2111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 2114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Ensure that each field is within its valid range by calling {@link 2119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* #validateField(int)} on each field that has been set. This method 2120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* should only be called if this calendar is not lenient. 2121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @see #isLenient 2122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @see #validateField(int) 2123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::validateFields(UErrorCode &status) { 2125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t field = 0; U_SUCCESS(status) && (field < UCAL_FIELD_COUNT); field++) { 2126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isSet((UCalendarDateFields)field)) { 2127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru validateField((UCalendarDateFields)field, status); 2128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Validate a single field of this calendar. Subclasses should 2134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* override this method to validate any calendar-specific fields. 2135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Generic fields can be handled by 2136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <code>Calendar.validateField()</code>. 2137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @see #validateField(int, int, int) 2138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::validateField(UCalendarDateFields field, UErrorCode &status) { 2140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t y; 2141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 2142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_MONTH: 2143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru y = handleGetExtendedYear(); 2144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru validateField(field, 1, handleGetMonthLength(y, internalGet(UCAL_MONTH)), status); 2145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_YEAR: 2147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru y = handleGetExtendedYear(); 2148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru validateField(field, 1, handleGetYearLength(y), status); 2149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK_IN_MONTH: 2151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (internalGet(field) == 0) { 2152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ILLEGAL ARG because DOW in month cannot be 0\n", 2154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__); 2155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; // "DAY_OF_WEEK_IN_MONTH cannot be zero" 2157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru validateField(field, getMinimum(field), getMaximum(field), status); 2160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 2162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru validateField(field, getMinimum(field), getMaximum(field), status); 2163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Validate a single field of this calendar given its minimum and 2169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* maximum allowed value. If the field is out of range, throw a 2170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* descriptive <code>IllegalArgumentException</code>. Subclasses may 2171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* use this method in their implementation of {@link 2172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* #validateField(int)}. 2173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::validateField(UCalendarDateFields field, int32_t min, int32_t max, UErrorCode& status) 2175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t value = fFields[field]; 2177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (value < min || value > max) { 2178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ILLEGAL ARG because of field %s out of range %d..%d at %d\n", 2180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__,fldName(field),min,max,value); 2181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 2183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------- 2188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UFieldResolutionTable* Calendar::getFieldResolutionTable() const { 2190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return kDatePrecedence; 2191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUCalendarDateFields Calendar::newerField(UCalendarDateFields defaultField, UCalendarDateFields alternateField) const 2195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fStamp[alternateField] > fStamp[defaultField]) { 2197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return alternateField; 2198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return defaultField; 2200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUCalendarDateFields Calendar::resolveFields(const UFieldResolutionTable* precedenceTable) { 2203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t bestField = UCAL_FIELD_COUNT; 2204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t g=0; precedenceTable[g][0][0] != -1 && (bestField == UCAL_FIELD_COUNT); ++g) { 2205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t bestStamp = kUnset; 2206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t l=0; precedenceTable[g][l][0] != -1; ++l) { 2207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lineStamp = kUnset; 2208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Skip over first entry if it is negative 2209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t i=((precedenceTable[g][l][0]>=kResolveRemap)?1:0); precedenceTable[g][l][i]!=-1; ++i) { 2210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t s = fStamp[precedenceTable[g][l][i]]; 2211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If any field is unset then don't use this line 2212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (s == kUnset) { 2213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto linesInGroup; 2214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(s > lineStamp) { 2215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lineStamp = s; 2216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Record new maximum stamp & field no. 2219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (lineStamp > bestStamp) { 2220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bestStamp = lineStamp; 2221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bestField = precedenceTable[g][l][0]; // First field refers to entire line 2222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerulinesInGroup: 2224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ; 2225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return (UCalendarDateFields)( (bestField>=kResolveRemap)?(bestField&(kResolveRemap-1)):bestField ); 2228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UFieldResolutionTable Calendar::kDatePrecedence[] = 2231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_DAY_OF_MONTH, kResolveSTOP }, 2234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_WEEK_OF_YEAR, UCAL_DAY_OF_WEEK, kResolveSTOP }, 2235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_WEEK_OF_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP }, 2236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP }, 2237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_WEEK_OF_YEAR, UCAL_DOW_LOCAL, kResolveSTOP }, 2238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_WEEK_OF_MONTH, UCAL_DOW_LOCAL, kResolveSTOP }, 2239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP }, 2240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_DAY_OF_YEAR, kResolveSTOP }, 2241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { kResolveRemap | UCAL_DAY_OF_MONTH, UCAL_YEAR, kResolveSTOP }, // if YEAR is set over YEAR_WOY use DAY_OF_MONTH 2242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { kResolveRemap | UCAL_WEEK_OF_YEAR, UCAL_YEAR_WOY, kResolveSTOP }, // if YEAR_WOY is set, calc based on WEEK_OF_YEAR 2243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { kResolveSTOP } 2244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }, 2245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_WEEK_OF_YEAR, kResolveSTOP }, 2247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_WEEK_OF_MONTH, kResolveSTOP }, 2248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_DAY_OF_WEEK_IN_MONTH, kResolveSTOP }, 2249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DAY_OF_WEEK, kResolveSTOP }, 2250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { kResolveRemap | UCAL_DAY_OF_WEEK_IN_MONTH, UCAL_DOW_LOCAL, kResolveSTOP }, 2251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { kResolveSTOP } 2252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }, 2253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {{kResolveSTOP}} 2254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 2255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UFieldResolutionTable Calendar::kDOWPrecedence[] = 2258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_DAY_OF_WEEK,kResolveSTOP, kResolveSTOP }, 2261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_DOW_LOCAL,kResolveSTOP, kResolveSTOP }, 2262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {kResolveSTOP} 2263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }, 2264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {{kResolveSTOP}} 2265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 2266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// precedence for calculating a year 2268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst UFieldResolutionTable Calendar::kYearPrecedence[] = 2269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_YEAR, kResolveSTOP }, 2272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_EXTENDED_YEAR, kResolveSTOP }, 2273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { UCAL_YEAR_WOY, UCAL_WEEK_OF_YEAR, kResolveSTOP }, // YEAR_WOY is useless without WEEK_OF_YEAR 2274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { kResolveSTOP } 2275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }, 2276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru {{kResolveSTOP}} 2277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 2278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------- 2281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::computeTime(UErrorCode& status) { 2284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!isLenient()) { 2285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru validateFields(status); 2286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 2287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 2288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute the Julian day 2292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t julianDay = computeJulianDay(); 2293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2294b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double millis = Grego::julianDayToMillis(julianDay); 2295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // int32_t julianInsanityCheck = (int32_t)Math::floorDivide(millis, kOneDay); 2298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // julianInsanityCheck += kEpochStartAsJulianDay; 2299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if(1 || julianInsanityCheck != julianDay) { 2300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // fprintf(stderr, "%s:%d- D'oh- computed jules %d, to mills (%s)%.lf, recomputed %d\n", 2301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // __FILE__, __LINE__, julianDay, millis<0.0?"NEG":"", millis, julianInsanityCheck); 2302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // } 2303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t millisInDay; 2306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We only use MILLISECONDS_IN_DAY if it has been set by the user. 2308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This makes it possible for the caller to set the calendar to a 2309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // time and call clear(MONTH) to reset the MONTH to January. This 2310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is legacy behavior. Without this, clear(MONTH) has no effect, 2311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // since the internally set JULIAN_DAY is used. 2312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fStamp[UCAL_MILLISECONDS_IN_DAY] >= ((int32_t)kMinimumUserStamp) && 2313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newestStamp(UCAL_AM_PM, UCAL_MILLISECOND, kUnset) <= fStamp[UCAL_MILLISECONDS_IN_DAY]) { 2314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay = internalGet(UCAL_MILLISECONDS_IN_DAY); 2315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay = computeMillisInDay(); 2317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute the time zone offset and DST offset. There are two potential 2320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // ambiguities here. We'll assume a 2:00 am (wall time) switchover time 2321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // for discussion purposes here. 2322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1. The transition into DST. Here, a designated time of 2:00 am - 2:59 am 2323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // can be in standard or in DST depending. However, 2:00 am is an invalid 2324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST). 2325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We assume standard time, that is, 2:30 am is interpreted as 3:30 am DST. 2326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 2. The transition out of DST. Here, a designated time of 1:00 am - 1:59 am 2327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // can be in standard or DST. Both are valid representations (the rep 2328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // jumps from 1:59:59 DST to 1:00:00 Std). 2329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Again, we assume standard time, that is, 1:30 am is interpreted as 1:30 am Std. 2330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET 2331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // or DST_OFFSET fields; then we use those fields. 2332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fStamp[UCAL_ZONE_OFFSET] >= ((int32_t)kMinimumUserStamp) || 2333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fStamp[UCAL_DST_OFFSET] >= ((int32_t)kMinimumUserStamp)) { 2334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay -= internalGet(UCAL_ZONE_OFFSET) + internalGet(UCAL_DST_OFFSET); 2335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay -= computeZoneOffset(millis, millisInDay,status); 2337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSetTime(millis + millisInDay); 2340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Compute the milliseconds in the day from the fields. This is a 2344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* value from 0 to 23:59:59.999 inclusive, unless fields are out of 2345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* range, in which case it can be an arbitrary value. This value 2346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* reflects local zone wall time. 2347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @stable ICU 2.0 2348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::computeMillisInDay() { 2350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Do the time portion of the conversion. 2351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t millisInDay = 0; 2353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the best set of fields specifying the time of day. There 2355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // are only two possibilities here; the HOUR_OF_DAY or the 2356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // AM_PM and the HOUR. 2357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t hourOfDayStamp = fStamp[UCAL_HOUR_OF_DAY]; 2358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t hourStamp = (fStamp[UCAL_HOUR] > fStamp[UCAL_AM_PM])?fStamp[UCAL_HOUR]:fStamp[UCAL_AM_PM]; 2359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp; 2360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Hours 2362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestStamp != kUnset) { 2363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestStamp == hourOfDayStamp) { 2364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Don't normalize here; let overflow bump into the next period. 2365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This is consistent with how we handle other fields. 2366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay += internalGet(UCAL_HOUR_OF_DAY); 2367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Don't normalize here; let overflow bump into the next period. 2369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This is consistent with how we handle other fields. 2370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay += internalGet(UCAL_HOUR); 2371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay += 12 * internalGet(UCAL_AM_PM); // Default works for unset AM_PM 2372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We use the fact that unset == 0; we start with millisInDay 2376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // == HOUR_OF_DAY. 2377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay *= 60; 2378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay += internalGet(UCAL_MINUTE); // now have minutes 2379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay *= 60; 2380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay += internalGet(UCAL_SECOND); // now have seconds 2381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay *= 1000; 2382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millisInDay += internalGet(UCAL_MILLISECOND); // now have millis 2383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return millisInDay; 2385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* This method can assume EXTENDED_YEAR has been set. 2389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @param millis milliseconds of the date fields 2390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @param millisInDay milliseconds of the time fields; may be out 2391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* or range. 2392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @stable ICU 2.0 2393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::computeZoneOffset(double millis, int32_t millisInDay, UErrorCode &ec) { 2395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rawOffset, dstOffset; 2396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getTimeZone().getOffset(millis+millisInDay, TRUE, rawOffset, dstOffset, ec); 2397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return rawOffset + dstOffset; 2398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Note: Because we pass in wall millisInDay, rather than 2399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // standard millisInDay, we interpret "1:00 am" on the day 2400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of cessation of DST as "1:00 am Std" (assuming the time 2401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of cessation is 2:00 am). 2402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::computeJulianDay() 2405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We want to see if any of the date fields is newer than the 2407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // JULIAN_DAY. If not, then we use JULIAN_DAY. If so, then we do 2408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the normal resolution. We only use JULIAN_DAY if it has been 2409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // set by the user. This makes it possible for the caller to set 2410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the calendar to a time and call clear(MONTH) to reset the MONTH 2411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // to January. This is legacy behavior. Without this, 2412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clear(MONTH) has no effect, since the internally set JULIAN_DAY 2413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // is used. 2414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fStamp[UCAL_JULIAN_DAY] >= (int32_t)kMinimumUserStamp) { 2415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t bestStamp = newestStamp(UCAL_ERA, UCAL_DAY_OF_WEEK_IN_MONTH, kUnset); 2416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bestStamp = newestStamp(UCAL_YEAR_WOY, UCAL_EXTENDED_YEAR, bestStamp); 2417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestStamp <= fStamp[UCAL_JULIAN_DAY]) { 2418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return internalGet(UCAL_JULIAN_DAY); 2419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCalendarDateFields bestField = resolveFields(getFieldResolutionTable()); 2423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestField == UCAL_FIELD_COUNT) { 2424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bestField = UCAL_DAY_OF_MONTH; 2425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return handleComputeJulianDay(bestField); 2428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------------- 2431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::handleComputeJulianDay(UCalendarDateFields bestField) { 2433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool useMonth = (bestField == UCAL_DAY_OF_MONTH || 2434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bestField == UCAL_WEEK_OF_MONTH || 2435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru bestField == UCAL_DAY_OF_WEEK_IN_MONTH); 2436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t year; 2437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestField == UCAL_WEEK_OF_YEAR) { 2439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = internalGet(UCAL_YEAR_WOY, handleGetExtendedYear()); 2440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_EXTENDED_YEAR, year); 2441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = handleGetExtendedYear(); 2443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet(UCAL_EXTENDED_YEAR, year); 2444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: bestField= %s - y=%d\n", __FILE__, __LINE__, fldName(bestField), year); 2448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the Julian day of the day BEFORE the start of this year. 2451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If useMonth is true, get the day before the start of the month. 2452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // give calendar subclass a chance to have a default 'first' month 2454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t month; 2455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isSet(UCAL_MONTH)) { 2457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru month = internalGet(UCAL_MONTH); 2458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru month = getDefaultMonthInYear(); 2460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t julianDay = handleComputeMonthStart(year, useMonth ? month : 0, useMonth); 2463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestField == UCAL_DAY_OF_MONTH) { 2465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // give calendar subclass a chance to have a default 'first' dom 2467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dayOfMonth; 2468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(isSet(UCAL_DAY_OF_MONTH)) { 2469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayOfMonth = internalGet(UCAL_DAY_OF_MONTH,1); 2470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dayOfMonth = getDefaultDayInMonth(month); 2472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return julianDay + dayOfMonth; 2474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestField == UCAL_DAY_OF_YEAR) { 2477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return julianDay + internalGet(UCAL_DAY_OF_YEAR); 2478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw 2481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // At this point julianDay is the 0-based day BEFORE the first day of 2483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // January 1, year 1 of the given calendar. If julianDay == 0, it 2484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian 2485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // or Gregorian). (or it is before the month we are in, if useMonth is True) 2486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // At this point we need to process the WEEK_OF_MONTH or 2488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH. 2489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // First, perform initial shared computations. These locate the 2490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // first week of the period. 2491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the 0-based localized DOW of day one of the month or year. 2493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Valid range 0..6. 2494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; 2495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (first < 0) { 2496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru first += 7; 2497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dowLocal = getLocalDOW(); 2500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find the first target DOW (dowLocal) in the month or year. 2502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Actually, it may be just before the first of the month or year. 2503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // It will be an integer from -5..7. 2504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t date = 1 - first + dowLocal; 2505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (bestField == UCAL_DAY_OF_WEEK_IN_MONTH) { 2507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Adjust the target DOW to be in the month or year. 2508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (date < 1) { 2509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date += 7; 2510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The only trickiness occurs if the day-of-week-in-month is 2513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // negative. 2514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dim = internalGet(UCAL_DAY_OF_WEEK_IN_MONTH, 1); 2515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dim >= 0) { 2516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date += 7*(dim - 1); 2517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Move date to the last of this day-of-week in this month, 2520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // then back up as needed. If dim==-1, we don't back up at 2521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // all. If dim==-2, we back up once, etc. Don't back up 2522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // past the first of the given day-of-week in this month. 2523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Note that we handle -2, -3, etc. correctly, even though 2524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // values < -1 are technically disallowed. 2525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t m = internalGet(UCAL_MONTH, UCAL_JANUARY); 2526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t monthLength = handleGetMonthLength(year, m); 2527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date += ((monthLength - date) / 7 + dim + 1) * 7; 2528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - bf= %s\n", __FILE__, __LINE__, fldName(bestField)); 2532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(bestField == UCAL_WEEK_OF_YEAR) { // ------------------------------------- WOY ------------- 2535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!isSet(UCAL_YEAR_WOY) || // YWOY not set at all or 2536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ( (resolveFields(kYearPrecedence) != UCAL_YEAR_WOY) // YWOY doesn't have precedence 2537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru && (fStamp[UCAL_YEAR_WOY]!=kInternallySet) ) ) // (excluding where all fields are internally set - then YWOY is used) 2538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // need to be sure to stay in 'real' year. 2540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t woy = internalGet(bestField); 2541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nextJulianDay = handleComputeMonthStart(year+1, 0, FALSE); // jd of day before jan 1 2543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nextFirst = julianDayToDayOfWeek(nextJulianDay + 1) - firstDayOfWeek; 2544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nextFirst < 0) { // 0..6 ldow of Jan 1 2546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextFirst += 7; 2547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(woy==1) { // FIRST WEEK --------------------------------- 2550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - woy=%d, yp=%d, nj(%d)=%d, nf=%d", __FILE__, __LINE__, 2552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalGet(bestField), resolveFields(kYearPrecedence), year+1, 2553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextJulianDay, nextFirst); 2554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " next: %d DFW, min=%d \n", (7-nextFirst), getMinimalDaysInFirstWeek() ); 2556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // nextFirst is now the localized DOW of Jan 1 of y-woy+1 2559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((nextFirst > 0) && // Jan 1 starts on FDOW 2560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (7-nextFirst) >= getMinimalDaysInFirstWeek()) // or enough days in the week 2561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Jan 1 of (yearWoy+1) is in yearWoy+1 - recalculate JD to next year 2563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - was going to move JD from %d to %d [d%d]\n", __FILE__, __LINE__, 2565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru julianDay, nextJulianDay, (nextJulianDay-julianDay)); 2566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru julianDay = nextJulianDay; 2568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // recalculate 'first' [0-based local dow of jan 1] 2570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; 2571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (first < 0) { 2572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru first += 7; 2573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // recalculate date. 2575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date = 1 - first + dowLocal; 2576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(woy>=getLeastMaximum(bestField)) { 2578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // could be in the last week- find out if this JD would overstep 2579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t testDate = date; 2580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((7 - first) < getMinimalDaysInFirstWeek()) { 2581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testDate += 7; 2582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now adjust for the week number. 2585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testDate += 7 * (woy - 1); 2586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - y=%d, y-1=%d doy%d, njd%d (C.F. %d)\n", 2589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, year, year-1, testDate, julianDay+testDate, nextJulianDay); 2590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(julianDay+testDate > nextJulianDay) { // is it past Dec 31? (nextJulianDay is day BEFORE year+1's Jan 1) 2592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Fire up the calculating engines.. retry YWOY = (year-1) 2593b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru julianDay = handleComputeMonthStart(year-1, 0, FALSE); // jd before Jan 1 of previous year 2594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru first = julianDayToDayOfWeek(julianDay + 1) - firstDayOfWeek; // 0 based local dow of first week 2595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(first < 0) { // 0..6 2597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru first += 7; 2598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date = 1 - first + dowLocal; 2600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - date now %d, jd%d, ywoy%d\n", 2603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru __FILE__, __LINE__, date, julianDay, year-1); 2604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* correction needed */ 2608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* leastmaximum */ 2609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* resolvefields(year) != year_woy */ 2610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* bestfield != week_of_year */ 2611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR) 2613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Adjust for minimal days in first week 2614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((7 - first) < getMinimalDaysInFirstWeek()) { 2615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date += 7; 2616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now adjust for the week number. 2619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date += 7 * (internalGet(bestField) - 1); 2620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return julianDay + date; 2623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getDefaultMonthInYear() 2627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 2629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getDefaultDayInMonth(int32_t /*month*/) 2633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 1; 2635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::getLocalDOW() 2639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get zero-based localized DOW, valid range 0..6. This is the DOW 2641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we are looking for. 2642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dowLocal = 0; 2643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (resolveFields(kDOWPrecedence)) { 2644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK: 2645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dowLocal = internalGet(UCAL_DAY_OF_WEEK) - fFirstDayOfWeek; 2646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DOW_LOCAL: 2648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dowLocal = internalGet(UCAL_DOW_LOCAL) - 1; 2649b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 2651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dowLocal = dowLocal % 7; 2654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dowLocal < 0) { 2655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dowLocal += 7; 2656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dowLocal; 2658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::handleGetExtendedYearFromWeekFields(int32_t yearWoy, int32_t woy) 2661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We have UCAL_YEAR_WOY and UCAL_WEEK_OF_YEAR - from those, determine 2663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // what year we fall in, so that other code can set it properly. 2664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // (code borrowed from computeWeekFields and handleComputeJulianDay) 2665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //return yearWoy; 2666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // First, we need a reliable DOW. 2668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UCalendarDateFields bestField = resolveFields(kDatePrecedence); // !! Note: if subclasses have a different table, they should override handleGetExtendedYearFromWeekFields 2669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now, a local DOW 2671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dowLocal = getLocalDOW(); // 0..6 2672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t firstDayOfWeek = getFirstDayOfWeek(); // Localized fdw 2673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t jan1Start = handleComputeMonthStart(yearWoy, 0, FALSE); 2674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nextJan1Start = handleComputeMonthStart(yearWoy+1, 0, FALSE); // next year's Jan1 start 2675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // At this point julianDay is the 0-based day BEFORE the first day of 2677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // January 1, year 1 of the given calendar. If julianDay == 0, it 2678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian 2679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // or Gregorian). (or it is before the month we are in, if useMonth is True) 2680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // At this point we need to process the WEEK_OF_MONTH or 2682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH. 2683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // First, perform initial shared computations. These locate the 2684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // first week of the period. 2685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the 0-based localized DOW of day one of the month or year. 2687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Valid range 0..6. 2688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t first = julianDayToDayOfWeek(jan1Start + 1) - firstDayOfWeek; 2689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (first < 0) { 2690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru first += 7; 2691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nextFirst = julianDayToDayOfWeek(nextJan1Start + 1) - firstDayOfWeek; 2693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nextFirst < 0) { 2694b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru nextFirst += 7; 2695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t minDays = getMinimalDaysInFirstWeek(); 2698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool jan1InPrevYear = FALSE; // January 1st in the year of WOY is the 1st week? (i.e. first week is < minimal ) 2699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //UBool nextJan1InPrevYear = FALSE; // January 1st of Year of WOY + 1 is in the first week? 2700b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2701b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((7 - first) < minDays) { 2702b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jan1InPrevYear = TRUE; 2703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if((7 - nextFirst) < minDays) { 2706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // nextJan1InPrevYear = TRUE; 2707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // } 2708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(bestField) { 2710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_YEAR: 2711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(woy == 1) { 2712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(jan1InPrevYear == TRUE) { 2713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the first week of January is in the previous year 2714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // therefore WOY1 is always solidly within yearWoy 2715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; 2716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2717b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // First WOY is split between two years 2718b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( dowLocal < first) { // we are prior to Jan 1 2719b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy-1; // previous year 2720b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2721b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; // in this year 2722b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2723b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2724b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(woy >= getLeastMaximum(bestField)) { 2725b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we _might_ be in the last week.. 2726b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t jd = // Calculate JD of our target day: 2727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jan1Start + // JD of Jan 1 2728b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (7-first) + // days in the first week (Jan 1.. ) 2729b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (woy-1)*7 + // add the weeks of the year 2730b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dowLocal; // the local dow (0..6) of last week 2731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(jan1InPrevYear==FALSE) { 2732b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru jd -= 7; // woy already includes Jan 1's week. 2733b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2734b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if( (jd+1) >= nextJan1Start ) { 2736b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we are in week 52 or 53 etc. - actual year is yearWoy+1 2737b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy+1; 2738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // still in yearWoy; 2740b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; 2741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2742b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we're not possibly in the last week -must be ywoy 2744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; 2745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2746b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DATE: 2749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if((internalGet(UCAL_MONTH)==0) && 2750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (woy >= getLeastMaximum(UCAL_WEEK_OF_YEAR))) { 2751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy+1; // month 0, late woy = in the next year 2752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if(woy==1) { 2753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //if(nextJan1InPrevYear) { 2754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(internalGet(UCAL_MONTH)==0) { 2755b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; 2756b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2757b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy-1; 2758b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //} 2760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //(internalGet(UCAL_DATE) <= (7-first)) /* && in minDow */ ) { 2763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //within 1st week and in this month.. 2764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //return yearWoy+1; 2765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; 2766b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2767b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: // assume the year is appropriate 2769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; 2770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - forgot a return on field %s\n", __FILE__, __LINE__, fldName(bestField)); 2775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return yearWoy; 2778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const 2781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return handleComputeMonthStart(extendedYear, month+1, TRUE) - 2783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru handleComputeMonthStart(extendedYear, month, TRUE); 2784b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2785b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2786b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::handleGetYearLength(int32_t eyear) const { 2787b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return handleComputeMonthStart(eyear+1, 0, FALSE) - 2788b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru handleComputeMonthStart(eyear, 0, FALSE); 2789b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 2792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getActualMaximum(UCalendarDateFields field, UErrorCode& status) const 2793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result; 2795b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 2796b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DATE: 2797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) return 0; 2799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar *cal = clone(); 2800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!cal) { status = U_MEMORY_ALLOCATION_ERROR; return 0; } 2801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cal->prepareGetActual(field,FALSE,status); 2802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = handleGetMonthLength(cal->get(UCAL_EXTENDED_YEAR, status), cal->get(UCAL_MONTH, status)); 2803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete cal; 2804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_YEAR: 2808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) return 0; 2810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar *cal = clone(); 2811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!cal) { status = U_MEMORY_ALLOCATION_ERROR; return 0; } 2812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cal->prepareGetActual(field,FALSE,status); 2813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = handleGetYearLength(cal->get(UCAL_EXTENDED_YEAR, status)); 2814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete cal; 2815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK: 2819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_AM_PM: 2820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR: 2821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_HOUR_OF_DAY: 2822b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MINUTE: 2823b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_SECOND: 2824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECOND: 2825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_ZONE_OFFSET: 2826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DST_OFFSET: 2827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DOW_LOCAL: 2828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_JULIAN_DAY: 2829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MILLISECONDS_IN_DAY: 2830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // These fields all have fixed minima/maxima 2831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = getMaximum(field); 2832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2833b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 2835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // For all other fields, do it the hard way.... 2836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = getActualHelper(field, getLeastMaximum(field), getMaximum(field),status); 2837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 2840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 2844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Prepare this calendar for computing the actual minimum or maximum. 2845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* This method modifies this calendar's fields; it is called on a 2846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* temporary calendar. 2847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 2848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <p>Rationale: The semantics of getActualXxx() is to return the 2849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* maximum or minimum value that the given field can take, taking into 2850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* account other relevant fields. In general these other fields are 2851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* larger fields. For example, when computing the actual maximum 2852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* DATE, the current value of DATE itself is ignored, 2853b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* as is the value of any field smaller. 2854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 2855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <p>The time fields all have fixed minima and maxima, so we don't 2856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* need to worry about them. This also lets us set the 2857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* MILLISECONDS_IN_DAY to zero to erase any effects the time fields 2858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* might have when computing date fields. 2859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 2860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* <p>DAY_OF_WEEK is adjusted specially for the WEEK_OF_MONTH and 2861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* WEEK_OF_YEAR fields to ensure that they are computed correctly. 2862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* @internal 2863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 2864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid Calendar::prepareGetActual(UCalendarDateFields field, UBool isMinimum, UErrorCode &status) 2865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_MILLISECONDS_IN_DAY, 0); 2867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (field) { 2869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR: 2870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_YEAR_WOY: 2871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_EXTENDED_YEAR: 2872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DAY_OF_YEAR, getGreatestMinimum(UCAL_DAY_OF_YEAR)); 2873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_MONTH: 2876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, getGreatestMinimum(UCAL_DATE)); 2877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_DAY_OF_WEEK_IN_MONTH: 2880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // For dowim, the maximum occurs for the DOW of the first of the 2881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // month. 2882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DATE, 1); 2883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DAY_OF_WEEK, get(UCAL_DAY_OF_WEEK, status)); // Make this user set 2884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_MONTH: 2887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case UCAL_WEEK_OF_YEAR: 2888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If we're counting weeks, set the day of the week to either the 2889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // first or last localized DOW. We know the last week of a month 2890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // or year will contain the first day of the week, and that the 2891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // first week will contain the last DOW. 2892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 2893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dow = fFirstDayOfWeek; 2894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isMinimum) { 2895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dow = (dow + 6) % 7; // set to last DOW 2896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (dow < UCAL_SUNDAY) { 2897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru dow += 7; 2898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "prepareGetActualHelper(WOM/WOY) - dow=%d\n", dow); 2902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2903b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(UCAL_DAY_OF_WEEK, dow); 2904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 2907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ; 2908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2910b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Do this last to give it the newest time stamp 2911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru set(field, getGreatestMinimum(field)); 2912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t Calendar::getActualHelper(UCalendarDateFields field, int32_t startValue, int32_t endValue, UErrorCode &status) const 2915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "getActualHelper(%d,%d .. %d, %s)\n", field, startValue, endValue, u_errorName(status)); 2918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (startValue == endValue) { 2920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // if we know that the maximum value is always the same, just return it 2921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return startValue; 2922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2924b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t delta = (endValue > startValue) ? 1 : -1; 2925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // clone the calendar so we don't mess with the real one, and set it to 2927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // accept anything for the field values 2928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) return startValue; 2929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Calendar *work = clone(); 2930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(!work) { status = U_MEMORY_ALLOCATION_ERROR; return startValue; } 2931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru work->setLenient(TRUE); 2932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status)); 2934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru work->prepareGetActual(field, delta < 0, status); 2936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status)); 2938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // now try each value from the start to the end one by one until 2941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we get a value that normalizes to another value. The last value that 2942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // normalizes to itself is the actual maximum for the current date 2943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t result = startValue; 2944b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 2945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - getActualHelper - %s\n", __FILE__, __LINE__, u_errorName(status)); 2947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru work->set(field, startValue); 2949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d - getActualHelper - %s (set to %d)\n", __FILE__, __LINE__, u_errorName(status), startValue); 2951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (work->get(field, status) != startValue) { 2953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "getActualHelper(fld %d) - got %d (not %d), BREAK - %s\n", field, work->get(field,status), startValue, u_errorName(status)); 2955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 2957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 2958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = startValue; 2959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startValue += delta; 2960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "getActualHelper(%d) result=%d (start), start += %d to %d\n", field, result, delta, startValue); 2962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 2964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (result != endValue && U_SUCCESS(status)); 2965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete work; 2966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 2967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "getActualHelper(%d) = %d\n", field, result); 2968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 2969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return result; 2970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 2971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ------------------------------------- 2976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 2978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::setWeekCountData(const Locale& desiredLocale, const char *type, UErrorCode& status) 2979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 2980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Read the week count data from the resource bundle. This should 2981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // have the form: 2982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 2983b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // DateTimeElements:intvector { 2984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1, // first day of week 2985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1 // min days in week 2986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // } 2987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Both have a range of 1..7 2988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) return; 2991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstDayOfWeek = UCAL_SUNDAY; 2993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fMinimalDaysInFirstWeek = 1; 2994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 2995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CalendarData calData(desiredLocale, type, status); 2996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the resource data doesn't seem to be present at all, then use last-resort 2997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // hard-coded data. 2998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *dateTimeElements = calData.getByKey(gDateTimeElements, status); 2999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) 3001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 3002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CALDATA) 3003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " Failure loading dateTimeElements = %s\n", u_errorName(status)); 3004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 3005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_USING_FALLBACK_WARNING; 3006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 3007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 3008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_LOCALE_BASED(locBased, *this); 3010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru locBased.setLocaleIDs(ures_getLocaleByType(dateTimeElements, ULOC_VALID_LOCALE, &status), 3011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_getLocaleByType(dateTimeElements, ULOC_ACTUAL_LOCALE, &status)); 3012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(status)) { 3013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined (U_DEBUG_CAL) 3014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, " Valid=%s, Actual=%s\n", validLocale, actualLocale); 3015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 3016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t arrLen; 3017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int32_t *dateTimeElementsArr = ures_getIntVector(dateTimeElements, &arrLen, &status); 3018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_SUCCESS(status) && arrLen == 2 3020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru && 1 <= dateTimeElementsArr[0] && dateTimeElementsArr[0] <= 7 3021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru && 1 <= dateTimeElementsArr[1] && dateTimeElementsArr[1] <= 7) 3022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 3023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fFirstDayOfWeek = (UCalendarDaysOfWeek)dateTimeElementsArr[0]; 3024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fMinimalDaysInFirstWeek = (uint8_t)dateTimeElementsArr[1]; 3025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 3026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 3027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_INVALID_FORMAT_ERROR; 3028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 3029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 3030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // do NOT close dateTimeElements 3032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 3033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 3035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Recompute the time and update the status fields isTimeSet 3036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* and areFieldsSet. Callers should check isTimeSet and only 3037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* call this method if isTimeSet is false. 3038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 3039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 3040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::updateTime(UErrorCode& status) 3041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 3042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru computeTime(status); 3043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) 3044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 3045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If we are lenient, we need to recompute the fields to normalize 3047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the values. Also, if we haven't set all the fields yet (i.e., 3048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // in a newly-created object), we need to fill in the fields. [LIU] 3049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isLenient() || ! fAreAllFieldsSet) 3050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsSet = FALSE; 3051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fIsTimeSet = TRUE; 3053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fAreFieldsVirtuallySet = FALSE; 3054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 3055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLocale 3057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getLocale(ULocDataLocaleType type, UErrorCode& status) const { 3058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_LOCALE_BASED(locBased, *this); 3059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return locBased.getLocale(type, status); 3060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 3061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst char * 3063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::getLocaleID(ULocDataLocaleType type, UErrorCode& status) const { 3064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_LOCALE_BASED(locBased, *this); 3065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return locBased.getLocaleID(type, status); 3066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 3067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Deprecated function. This doesn't need to be inline. 3069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 3070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruCalendar::internalSet(EDateFields field, int32_t value) 3071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 3072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru internalSet((UCalendarDateFields) field, value); 3073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 3074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 3076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 3078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof 3081