1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)****************************************************************************** 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2003-2010, International Business Machines Corporation 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* and others. All Rights Reserved. 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)****************************************************************************** 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* File ISLAMCAL.H 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Modification History: 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Date Name Description 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 10/14/2003 srl ported from java IslamicCalendar 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)***************************************************************************** 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "islamcal.h" 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h" 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <float.h> 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "gregoimp.h" // Math 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "astro.h" // CalendarAstronomer 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uhash.h" 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucln_in.h" 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const UDate HIJRA_MILLIS = -42521587200000.0; // 7/16/622 AD 00:00 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Debugging 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef U_DEBUG_ISLAMCAL 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# include <stdio.h> 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# include <stdarg.h> 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void debug_islamcal_loc(const char *f, int32_t l) 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fprintf(stderr, "%s:%d: ", f, l); 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static void debug_islamcal_msg(const char *pat, ...) 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_list ap; 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) va_start(ap, pat); 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) vfprintf(stderr, pat, ap); 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fflush(stderr); 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// must use double parens, i.e.: U_DEBUG_ISLAMCAL_MSG(("four is: %d",4)); 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define U_DEBUG_ISLAMCAL_MSG(x) {debug_islamcal_loc(__FILE__,__LINE__);debug_islamcal_msg x;} 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define U_DEBUG_ISLAMCAL_MSG(x) 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// --- The cache -- 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// cache of months 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX astroLock = 0; // pod bay door lock 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_NAMESPACE_QUALIFIER CalendarCache *gMonthCache = NULL; 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_NAMESPACE_QUALIFIER CalendarAstronomer *gIslamicCalendarAstro = NULL; 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_BEGIN 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UBool calendar_islamic_cleanup(void) { 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (gMonthCache) { 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete gMonthCache; 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gMonthCache = NULL; 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (gIslamicCalendarAstro) { 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delete gIslamicCalendarAstro; 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gIslamicCalendarAstro = NULL; 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_destroy(&astroLock); 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CDECL_END 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_BEGIN 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Implementation of the IslamicCalendar class 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Constructors... 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const char *IslamicCalendar::getType() const { 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(civil==CIVIL) { 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return "islamic-civil"; 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return "islamic"; 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Calendar* IslamicCalendar::clone() const { 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return new IslamicCalendar(*this); 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)IslamicCalendar::IslamicCalendar(const Locale& aLocale, UErrorCode& success, ECivil beCivil) 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles): Calendar(TimeZone::createDefault(), aLocale, success), 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)civil(beCivil) 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly. 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)IslamicCalendar::IslamicCalendar(const IslamicCalendar& other) : Calendar(other), civil(other.civil) { 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)IslamicCalendar::~IslamicCalendar() 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Determines whether this object uses the fixed-cycle Islamic civil calendar 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* or an approximation of the religious, astronomical calendar. 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param beCivil <code>true</code> to use the civil calendar, 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <code>false</code> to use the astronomical calendar. 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void IslamicCalendar::setCivil(ECivil beCivil, UErrorCode &status) 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (civil != beCivil) { 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The fields of the calendar will become invalid, because the calendar 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // rules are different 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate m = getTimeInMillis(status); 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) civil = beCivil; 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) clear(); 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) setTimeInMillis(m, status); 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Returns <code>true</code> if this object is using the fixed-cycle civil 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* calendar, or <code>false</code> if using the religious, astronomical 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* calendar. 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool IslamicCalendar::isCivil() { 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (civil == CIVIL); 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Minimum / Maximum access functions 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Note: Current IslamicCalendar implementation does not work 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// well with negative years. 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int32_t LIMITS[UCAL_FIELD_COUNT][4] = { 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Minimum Greatest Least Maximum 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Minimum Maximum 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 0, 0, 0, 0}, // ERA 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, 1, 5000000, 5000000}, // YEAR 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 0, 0, 11, 11}, // MONTH 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, 1, 50, 51}, // WEEK_OF_YEAR 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // WEEK_OF_MONTH 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, 1, 29, 30}, // DAY_OF_MONTH 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, 1, 354, 355}, // DAY_OF_YEAR 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { -1, -1, 5, 5}, // DAY_OF_WEEK_IN_MONTH 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, 1, 5000000, 5000000}, // YEAR_WOY 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 1, 1, 5000000, 5000000}, // EXTENDED_YEAR 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECONDS_IN_DAY 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // IS_LEAP_MONTH 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const { 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return LIMITS[field][limitType]; 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Assorted calculation utilities 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Determine whether a year is a leap year in the Islamic civil calendar 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool IslamicCalendar::civilLeapYear(int32_t year) 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (14 + 11 * year) % 30 < 11; 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Return the day # on which the given year starts. Days are counted 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* from the Hijri epoch, origin 0. 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::yearStart(int32_t year) { 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (civil == CIVIL) { 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (year-1)*354 + ClockMath::floorDivide((3+11*year),30); 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return trueMonthStart(12*(year-1)); 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Return the day # on which the given month starts. Days are counted 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* from the Hijri epoch, origin 0. 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param year The hijri year 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param year The hijri month, 0-based 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::monthStart(int32_t year, int32_t month) const { 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (civil == CIVIL) { 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (int32_t)uprv_ceil(29.5*month) 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) + (year-1)*354 + (int32_t)ClockMath::floorDivide((3+11*year),30); 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return trueMonthStart(12*(year-1) + month); 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Find the day number on which a particular month of the true/lunar 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Islamic calendar starts. 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param month The month in question, origin 0 from the Hijri epoch 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @return The day number on which the given month starts. 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::trueMonthStart(int32_t month) const 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t start = CalendarCache::get(&gMonthCache, month, status); 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (start==0) { 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Make a guess at when the month started, using the average length 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate origin = HIJRA_MILLIS 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) + uprv_floor(month * CalendarAstronomer::SYNODIC_MONTH) * kOneDay; 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // moonAge will fail due to memory allocation error 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double age = moonAge(origin, status); 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto trueMonthStartEnd; 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (age >= 0) { 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // The month has already started 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) origin -= kOneDay; 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) age = moonAge(origin, status); 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto trueMonthStartEnd; 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } while (age >= 0); 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) else { 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Preceding month has not ended yet. 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) do { 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) origin += kOneDay; 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) age = moonAge(origin, status); 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) goto trueMonthStartEnd; 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } while (age < 0); 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start = (int32_t)ClockMath::floorDivide((origin - HIJRA_MILLIS), (double)kOneDay) + 1; 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) CalendarCache::put(&gMonthCache, month, start, status); 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)trueMonthStartEnd : 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(U_FAILURE(status)) { 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) start = 0; 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return start; 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Return the "age" of the moon at the given time; this is the difference 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* in ecliptic latitude between the moon and the sun. This method simply 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* calls CalendarAstronomer.moonAge, converts to degrees, 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* and adjusts the result to be in the range [-180, 180]. 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param time The time at which the moon's age is desired, 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* in millis since 1/1/1970. 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)double IslamicCalendar::moonAge(UDate time, UErrorCode &status) 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double age = 0; 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(&astroLock); 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(gIslamicCalendarAstro == NULL) { 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gIslamicCalendarAstro = new CalendarAstronomer(); 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (gIslamicCalendarAstro == NULL) { 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return age; 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ucln_i18n_registerCleanup(UCLN_I18N_ISLAMIC_CALENDAR, calendar_islamic_cleanup); 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) gIslamicCalendarAstro->setTime(time); 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) age = gIslamicCalendarAstro->getMoonAge(); 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(&astroLock); 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Convert to degrees and normalize... 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) age = age * 180 / CalendarAstronomer::PI; 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (age > 180) { 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) age = age - 360; 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return age; 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//---------------------------------------------------------------------- 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Calendar framework 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//---------------------------------------------------------------------- 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Return the length (in days) of the given month. 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param year The hijri year 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @param year The hijri month, 0-based 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const { 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t length = 0; 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (civil == CIVIL) { 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length = 29 + (month+1) % 2; 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) { 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length++; 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) month = 12*(extendedYear-1) + month; 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) length = trueMonthStart(month+1) - trueMonthStart(month) ; 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return length; 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Return the number of days in the given Islamic year 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::handleGetYearLength(int32_t extendedYear) const { 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (civil == CIVIL) { 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 354 + (civilLeapYear(extendedYear) ? 1 : 0); 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t month = 12*(extendedYear-1); 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (trueMonthStart(month + 12) - trueMonthStart(month)); 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Functions for converting from field values to milliseconds.... 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Return JD of start of given month/year 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /* useMonth */) const { 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return monthStart(eyear, month) + 1948439; 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Functions for converting from milliseconds to field values 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//------------------------------------------------------------------------- 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::handleGetExtendedYear() { 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t year; 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) { 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) year = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) year = internalGet(UCAL_YEAR, 1); // Default to year 1 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return year; 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Override Calendar to compute several fields specific to the Islamic 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* calendar system. These are: 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <ul><li>ERA 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>YEAR 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>MONTH 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>DAY_OF_MONTH 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>DAY_OF_YEAR 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* <li>EXTENDED_YEAR</ul> 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* method is called. The getGregorianXxx() methods return Gregorian 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* calendar equivalents for the given Julian day. 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* @draft ICU 2.4 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) { 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t year, month, dayOfMonth, dayOfYear; 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate startDate; 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t days = julianDay - 1948440; 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (civil == CIVIL) { 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Use the civil calendar approximation, which is just arithmetic 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) year = (int)ClockMath::floorDivide( (double)(30 * days + 10646) , 10631.0 ); 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 ); 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) month = month<11?month:11; 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) startDate = monthStart(year, month); 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Guess at the number of elapsed full months since the epoch 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t months = (int32_t)uprv_floor((double)days / CalendarAstronomer::SYNODIC_MONTH); 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) startDate = uprv_floor(months * CalendarAstronomer::SYNODIC_MONTH); 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) double age = moonAge(internalGetTime(), status); 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status)) { 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) status = U_MEMORY_ALLOCATION_ERROR; 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return; 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if ( days - startDate >= 25 && age > 0) { 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If we're near the end of the month, assume next month and search backwards 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) months++; 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Find out the last time that the new moon was actually visible at this longitude 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // This returns midnight the night that the moon was visible at sunset. 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while ((startDate = trueMonthStart(months)) > days) { 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // If it was after the date in question, back up a month and try again 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) months--; 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) year = months / 12 + 1; 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) month = months % 12; 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dayOfMonth = (days - monthStart(year, month)) + 1; 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Now figure out the day of the year. 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dayOfYear = (days - monthStart(year, 0) + 1); 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalSet(UCAL_ERA, 0); 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalSet(UCAL_YEAR, year); 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalSet(UCAL_EXTENDED_YEAR, year); 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalSet(UCAL_MONTH, month); 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalSet(UCAL_DAY_OF_MONTH, dayOfMonth); 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) internalSet(UCAL_DAY_OF_YEAR, dayOfYear); 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)IslamicCalendar::inDaylightTime(UErrorCode& status) const 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // copied from GregorianCalendar 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_FAILURE(status) || (&(getTimeZone()) == NULL && !getTimeZone().useDaylightTime())) 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return FALSE; 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // Force an update of the state of the Calendar. 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ((IslamicCalendar*)this)->complete(status); // cast away const 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE); 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// default century 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const UDate IslamicCalendar::fgSystemDefaultCentury = DBL_MIN; 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int32_t IslamicCalendar::fgSystemDefaultCenturyYear = -1; 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate IslamicCalendar::fgSystemDefaultCenturyStart = DBL_MIN; 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::fgSystemDefaultCenturyStartYear = -1; 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool IslamicCalendar::haveDefaultCentury() const 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return TRUE; 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate IslamicCalendar::defaultCenturyStart() const 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return internalGetDefaultCenturyStart(); 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t IslamicCalendar::defaultCenturyStartYear() const 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return internalGetDefaultCenturyStartYear(); 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UDate 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)IslamicCalendar::internalGetDefaultCenturyStart() const 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // lazy-evaluate systemDefaultCenturyStart 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool needsUpdate; 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate); 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (needsUpdate) { 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) initializeSystemDefaultCentury(); 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // use defaultCenturyStart unless it's the flag value; 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // then use systemDefaultCenturyStart 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return fgSystemDefaultCenturyStart; 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)int32_t 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)IslamicCalendar::internalGetDefaultCenturyStartYear() const 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // lazy-evaluate systemDefaultCenturyStartYear 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool needsUpdate; 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UMTX_CHECK(NULL, (fgSystemDefaultCenturyStart == fgSystemDefaultCentury), needsUpdate); 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (needsUpdate) { 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) initializeSystemDefaultCentury(); 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // use defaultCenturyStart unless it's the flag value; 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // then use systemDefaultCenturyStartYear 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return fgSystemDefaultCenturyStartYear; 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)IslamicCalendar::initializeSystemDefaultCentury() 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){ 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // initialize systemDefaultCentury and systemDefaultCenturyYear based 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // on the current time. They'll be set to 80 years before 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // the current time. 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) IslamicCalendar calendar(Locale("@calendar=islamic-civil"),status); 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (U_SUCCESS(status)) 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) calendar.setTime(Calendar::getNow(), status); 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) calendar.add(UCAL_YEAR, -80, status); 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UDate newStart = calendar.getTime(status); 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t newYear = calendar.get(UCAL_YEAR, status); 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_lock(NULL); 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if (fgSystemDefaultCenturyStart == fgSystemDefaultCentury) 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) { 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fgSystemDefaultCenturyStartYear = newYear; 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) fgSystemDefaultCenturyStart = newStart; 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) umtx_unlock(NULL); 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // We have no recourse upon failure unless we want to propagate the failure 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) // out. 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicCalendar) 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_NAMESPACE_END 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 546