16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 2003-2013, International Business Machines Corporation 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* and others. All Rights Reserved. 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* File ISLAMCAL.H 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Modification History: 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Date Name Description 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 10/14/2003 srl ported from java IslamicCalendar 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org***************************************************************************** 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "islamcal.h" 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "umutex.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include <float.h> 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "gregoimp.h" // Math 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "astro.h" // CalendarAstronomer 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uhash.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ucln_in.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UDate HIJRA_MILLIS = -42521587200000.0; // 7/16/622 AD 00:00 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Debugging 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#ifdef U_DEBUG_ISLAMCAL 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org# include <stdio.h> 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org# include <stdarg.h> 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void debug_islamcal_loc(const char *f, int32_t l) 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fprintf(stderr, "%s:%d: ", f, l); 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic void debug_islamcal_msg(const char *pat, ...) 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org va_list ap; 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org va_start(ap, pat); 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org vfprintf(stderr, pat, ap); 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fflush(stderr); 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// must use double parens, i.e.: U_DEBUG_ISLAMCAL_MSG(("four is: %d",4)); 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define U_DEBUG_ISLAMCAL_MSG(x) {debug_islamcal_loc(__FILE__,__LINE__);debug_islamcal_msg x;} 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define U_DEBUG_ISLAMCAL_MSG(x) 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// --- The cache -- 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// cache of months 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UMutex astroLock = U_MUTEX_INITIALIZER; // pod bay door lock 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::CalendarCache *gMonthCache = NULL; 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::CalendarAstronomer *gIslamicCalendarAstro = NULL; 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool calendar_islamic_cleanup(void) { 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gMonthCache) { 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gMonthCache; 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gMonthCache = NULL; 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gIslamicCalendarAstro) { 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete gIslamicCalendarAstro; 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gIslamicCalendarAstro = NULL; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Implementation of the IslamicCalendar class 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Friday EPOC 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t CIVIL_EPOC = 1948440; 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Thursday EPOC 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t ASTRONOMICAL_EPOC = 1948439; 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t UMALQURA_YEAR_START = 1318; 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t UMALQURA_YEAR_END = 1480; 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int UMALQURA_MONTHLENGTH[] = { 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1318 -1322 */ "0101 0111 0100", "1001 0111 0110", "0100 1011 0111", "0010 0101 0111", "0101 0010 1011", 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0574, 0x0975, 0x06A7, 0x0257, 0x052B, 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1323 -1327 */ "0110 1001 0101", "0110 1100 1010", "1010 1101 0101", "0101 0101 1011", "0010 0101 1101", 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0695, 0x06CA, 0x0AD5, 0x055B, 0x025B, 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1328 -1332 */ "1001 0010 1101", "1100 1001 0101", "1101 0100 1010", "1110 1010 0101", "0110 1101 0010", 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x092D, 0x0C95, 0x0D4A, 0x0E5B, 0x025B, 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1333 -1337 */ "1010 1101 0101", "0101 0101 1010", "1010 1010 1011", "0100 0100 1011", "0110 1010 0101", 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0AD5, 0x055A, 0x0AAB, 0x044B, 0x06A5, 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1338 -1342 */ "0111 0101 0010", "1011 1010 1001", "0011 0111 0100", "1010 1011 0110", "0101 0101 0110", 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0752, 0x0BA9, 0x0374, 0x0AB6, 0x0556, 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1343 -1347 */ "1010 1010 1010", "1101 0101 0010", "1101 1010 1001", "0101 1101 0100", "1010 1110 1010", 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0AAA, 0x0D52, 0x0DA9, 0x05D4, 0x0AEA, 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1348 -1352 */ "0100 1101 1101", "0010 0110 1110", "1001 0010 1110", "1010 1010 0110", "1101 0101 0100", 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x04DD, 0x026E, 0x092E, 0x0AA6, 0x0D54, 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1353 -1357 */ "0101 1010 1010", "0101 1011 0101", "0010 1011 0100", "1001 0011 0111", "0100 1001 1011", 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x05AA, 0x05B5, 0x02B4, 0x0937, 0x049B, 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1358 -1362 */ "1010 0100 1011", "1011 0010 0101", "1011 0101 0100", "1011 0110 1010", "0101 0110 1101", 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0A4B, 0x0B25, 0x0B54, 0x0B6A, 0x056D, 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1363 -1367 */ "0100 1010 1101", "1010 0101 0101", "1101 0010 0101", "1110 1001 0010", "1110 1100 1001", 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x04AD, 0x0A55, 0x0D25, 0x0E92, 0x0EC9, 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1368 -1372 */ "0110 1101 0100", "1010 1110 1010", "0101 0110 1011", "0100 1010 1011", "0110 1000 0101", 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x06D4, 0x0ADA, 0x056B, 0x04AB, 0x0685, 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1373 -1377 */ "1011 0100 1001", "1011 1010 0100", "1011 1011 0010", "0101 1011 0101", "0010 1011 1010", 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0B49, 0x0BA4, 0x0BB2, 0x05B5, 0x02BA, 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1378 -1382 */ "1001 0101 1011", "0100 1010 1011", "0101 0101 0101", "0110 1011 0010", "0110 1101 1001", 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x095B, 0x04AB, 0x0555, 0x06B2, 0x06D9, 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1383 -1387 */ "0010 1110 1100", "1001 0110 1110", "0100 1010 1110", "1010 0101 0110", "1101 0010 1010", 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x02EC, 0x096E, 0x04AE, 0x0A56, 0x0D2A, 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1388 -1392 */ "1101 0101 0101", "0101 1010 1010", "1010 1011 0101", "0100 1011 1011", "0000 0101 1011", 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0D55, 0x05AA, 0x0AB5, 0x04BB, 0x005B, 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1393 -1397 */ "1001 0010 1011", "1010 1001 0101", "0011 0100 1010", "1011 1010 0101", "0101 1010 1010", 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x092B, 0x0A95, 0x034A, 0x0BA5, 0x05AA, 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1398 -1402 */ "1010 1011 0101", "0101 0101 0110", "1010 1001 0110", "1101 0100 1010", "1110 1010 0101", 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0AB5, 0x0556, 0x0A96, 0x0B4A, 0x0EA5, 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1403 -1407 */ "0111 0101 0010", "0110 1110 1001", "0011 0110 1010", "1010 1010 1101", "0101 0101 0101", 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0752, 0x06E9, 0x036A, 0x0AAD, 0x0555, 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1408 -1412 */ "1010 1010 0101", "1011 0101 0010", "1011 1010 1001", "0101 1011 0100", "1001 1011 1010", 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0AA5, 0x0B52, 0x0BA9, 0x05B4, 0x09BA, 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1413 -1417 */ "0100 1101 1011", "0010 0101 1101", "0101 0010 1101", "1010 1010 0101", "1010 1101 0100", 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x04DB, 0x025D, 0x052D, 0x0AA5, 0x0AD4, 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1418 -1422 */ "1010 1110 1010", "0101 0110 1101", "0100 1011 1101", "0010 0011 1101", "1001 0001 1101", 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0AEA, 0x056D, 0x04BD, 0x023D, 0x091D, 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1423 -1427 */ "1010 1001 0101", "1011 0100 1010", "1011 0101 1010", "0101 0110 1101", "0010 1011 0110", 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0A95, 0x0B4A, 0x0B5A, 0x056D, 0x02B6, 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1428 -1432 */ "1001 0011 1011", "0100 1001 1011", "0110 0101 0101", "0110 1010 1001", "0111 0101 0100", 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x093B, 0x049B, 0x0655, 0x06A9, 0x0754, 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1433 -1437 */ "1011 0110 1010", "0101 0110 1100", "1010 1010 1101", "0101 0101 0101", "1011 0010 1001", 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0B6A, 0x056C, 0x0AAD, 0x0555, 0x0B29, 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1438 -1442 */ "1011 1001 0010", "1011 1010 1001", "0101 1101 0100", "1010 1101 1010", "0101 0101 1010", 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0B92, 0x0BA9, 0x05D4, 0x0ADA, 0x055A, 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1443 -1447 */ "1010 1010 1011", "0101 1001 0101", "0111 0100 1001", "0111 0110 0100", "1011 1010 1010", 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0AAB, 0x0595, 0x0749, 0x0764, 0x0BAA, 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1448 -1452 */ "0101 1011 0101", "0010 1011 0110", "1010 0101 0110", "1110 0100 1101", "1011 0010 0101", 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x05B5, 0x02B6, 0x0A56, 0x0E4D, 0x0B25, 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1453 -1457 */ "1011 0101 0010", "1011 0110 1010", "0101 1010 1101", "0010 1010 1110", "1001 0010 1111", 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0B52, 0x0B6A, 0x05AD, 0x02AE, 0x092F, 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1458 -1462 */ "0100 1001 0111", "0110 0100 1011", "0110 1010 0101", "0110 1010 1100", "1010 1101 0110", 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0497, 0x064B, 0x06A5, 0x06AC, 0x0AD6, 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1463 -1467 */ "0101 0101 1101", "0100 1001 1101", "1010 0100 1101", "1101 0001 0110", "1101 1001 0101", 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x055D, 0x049D, 0x0A4D, 0x0D16, 0x0D95, 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1468 -1472 */ "0101 1010 1010", "0101 1011 0101", "0010 1001 1010", "1001 0101 1011", "0100 1010 1100", 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x05AA, 0x05B5, 0x029A, 0x095B, 0x04AC, 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1473 -1477 */ "0101 1001 0101", "0110 1100 1010", "0110 1110 0100", "1010 1110 1010", "0100 1111 0101", 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x0595, 0x06CA, 0x06E4, 0x0AEA, 0x04F5, 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //* 1478 -1480 */ "0010 1011 0110", "1001 0101 0110", "1010 1010 1010" 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x02B6, 0x0956, 0x0AAA 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t getUmalqura_MonthLength(int32_t y, int32_t m) { 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t mask = (int32_t) (0x01 << (11 - m)); // set mask for bit corresponding to month 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if((UMALQURA_MONTHLENGTH[y] & mask) == 0 ) 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 29; 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 30; 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Constructors... 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst char *IslamicCalendar::getType() const { 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const char *sType = NULL; 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch (cType) { 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case CIVIL: 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sType = "islamic-civil"; 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case ASTRONOMICAL: 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sType = "islamic"; 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case TBLA: 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sType = "islamic-tbla"; 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UMALQURA: 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sType = "islamic-umalqura"; 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(false); // out of range 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sType = "islamic"; // "islamic" is used as the generic type 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return sType; 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgCalendar* IslamicCalendar::clone() const { 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new IslamicCalendar(*this); 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgIslamicCalendar::IslamicCalendar(const Locale& aLocale, UErrorCode& success, ECalculationType type) 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: Calendar(TimeZone::createDefault(), aLocale, success), 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgcType(type) 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly. 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgIslamicCalendar::IslamicCalendar(const IslamicCalendar& other) : Calendar(other), cType(other.cType) { 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgIslamicCalendar::~IslamicCalendar() 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid IslamicCalendar::setCalculationType(ECalculationType type, UErrorCode &status) 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cType != type) { 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The fields of the calendar will become invalid, because the calendar 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // rules are different 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate m = getTimeInMillis(status); 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cType = type; 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org clear(); 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setTimeInMillis(m, status); 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Returns <code>true</code> if this object is using the fixed-cycle civil 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* calendar, or <code>false</code> if using the religious, astronomical 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* calendar. 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @draft ICU 2.4 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool IslamicCalendar::isCivil() { 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (cType == CIVIL); 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Minimum / Maximum access functions 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Note: Current IslamicCalendar implementation does not work 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// well with negative years. 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// TODO: In some cases the current ICU Islamic calendar implementation shows 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// a month as having 31 days. Since date parsing now uses range checks based 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// on the table below, we need to change the range for last day of month to 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// include 31 as a workaround until the implementation is fixed. 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t LIMITS[UCAL_FIELD_COUNT][4] = { 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Minimum Greatest Least Maximum 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Minimum Maximum 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 0, 0, 0, 0}, // ERA 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1, 1, 5000000, 5000000}, // YEAR 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 0, 0, 11, 11}, // MONTH 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1, 1, 50, 51}, // WEEK_OF_YEAR 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // WEEK_OF_MONTH 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1, 1, 29, 31}, // DAY_OF_MONTH - 31 to workaround for cal implementation bug, should be 30 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1, 1, 354, 355}, // DAY_OF_YEAR 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DAY_OF_WEEK 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { -1, -1, 5, 5}, // DAY_OF_WEEK_IN_MONTH 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // AM_PM 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // HOUR_OF_DAY 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MINUTE 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // SECOND 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECOND 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // ZONE_OFFSET 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DST_OFFSET 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1, 1, 5000000, 5000000}, // YEAR_WOY 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // DOW_LOCAL 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 1, 1, 5000000, 5000000}, // EXTENDED_YEAR 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // JULIAN_DAY 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // MILLISECONDS_IN_DAY 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org {/*N/A*/-1,/*N/A*/-1,/*N/A*/-1,/*N/A*/-1}, // IS_LEAP_MONTH 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @draft ICU 2.4 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::handleGetLimit(UCalendarDateFields field, ELimitType limitType) const { 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return LIMITS[field][limitType]; 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Assorted calculation utilities 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Determine whether a year is a leap year in the Islamic civil calendar 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool IslamicCalendar::civilLeapYear(int32_t year) 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (14 + 11 * year) % 30 < 11; 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Return the day # on which the given year starts. Days are counted 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* from the Hijri epoch, origin 0. 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::yearStart(int32_t year) const{ 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cType == CIVIL || cType == TBLA || 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (cType == UMALQURA && year < UMALQURA_YEAR_START)) 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org { 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (year-1)*354 + ClockMath::floorDivide((3+11*year),30); 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(cType==ASTRONOMICAL){ 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return trueMonthStart(12*(year-1)); 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t ys = yearStart(UMALQURA_YEAR_START-1); 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ys+= handleGetYearLength(UMALQURA_YEAR_START-1); 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int i=UMALQURA_YEAR_START; i< year; i++){ 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ys+= handleGetYearLength(i); 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ys; 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Return the day # on which the given month starts. Days are counted 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* from the Hijri epoch, origin 0. 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @param year The hijri year 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @param year The hijri month, 0-based 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::monthStart(int32_t year, int32_t month) const { 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cType == CIVIL || cType == TBLA) { 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (int32_t)uprv_ceil(29.5*month) 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + (year-1)*354 + (int32_t)ClockMath::floorDivide((3+11*year),30); 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(cType==ASTRONOMICAL){ 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return trueMonthStart(12*(year-1) + month); 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t ms = yearStart(year); 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int i=0; i< month; i++){ 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ms+= handleGetMonthLength(year, i); 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return ms; 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Find the day number on which a particular month of the true/lunar 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Islamic calendar starts. 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @param month The month in question, origin 0 from the Hijri epoch 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @return The day number on which the given month starts. 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::trueMonthStart(int32_t month) const 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t start = CalendarCache::get(&gMonthCache, month, status); 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (start==0) { 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Make a guess at when the month started, using the average length 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate origin = HIJRA_MILLIS 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org + uprv_floor(month * CalendarAstronomer::SYNODIC_MONTH) * kOneDay; 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // moonAge will fail due to memory allocation error 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double age = moonAge(origin, status); 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto trueMonthStartEnd; 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (age >= 0) { 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The month has already started 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org origin -= kOneDay; 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org age = moonAge(origin, status); 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto trueMonthStartEnd; 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while (age >= 0); 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Preceding month has not ended yet. 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org origin += kOneDay; 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org age = moonAge(origin, status); 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org goto trueMonthStartEnd; 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while (age < 0); 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start = (int32_t)ClockMath::floorDivide((origin - HIJRA_MILLIS), (double)kOneDay) + 1; 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org CalendarCache::put(&gMonthCache, month, start, status); 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgtrueMonthStartEnd : 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(status)) { 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org start = 0; 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return start; 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Return the "age" of the moon at the given time; this is the difference 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* in ecliptic latitude between the moon and the sun. This method simply 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* calls CalendarAstronomer.moonAge, converts to degrees, 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* and adjusts the result to be in the range [-180, 180]. 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @param time The time at which the moon's age is desired, 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* in millis since 1/1/1970. 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgdouble IslamicCalendar::moonAge(UDate time, UErrorCode &status) 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double age = 0; 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_lock(&astroLock); 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(gIslamicCalendarAstro == NULL) { 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gIslamicCalendarAstro = new CalendarAstronomer(); 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (gIslamicCalendarAstro == NULL) { 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return age; 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ucln_i18n_registerCleanup(UCLN_I18N_ISLAMIC_CALENDAR, calendar_islamic_cleanup); 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gIslamicCalendarAstro->setTime(time); 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org age = gIslamicCalendarAstro->getMoonAge(); 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_unlock(&astroLock); 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Convert to degrees and normalize... 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org age = age * 180 / CalendarAstronomer::PI; 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (age > 180) { 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org age = age - 360; 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return age; 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//---------------------------------------------------------------------- 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Calendar framework 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//---------------------------------------------------------------------- 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Return the length (in days) of the given month. 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @param year The hijri year 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @param year The hijri month, 0-based 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @draft ICU 2.4 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const { 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length = 0; 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cType == CIVIL || cType == TBLA || 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (cType == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) { 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length = 29 + (month+1) % 2; 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) { 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length++; 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(cType == ASTRONOMICAL){ 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = 12*(extendedYear-1) + month; 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length = trueMonthStart(month+1) - trueMonthStart(month) ; 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org length = getUmalqura_MonthLength(extendedYear - UMALQURA_YEAR_START, month); 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return length; 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Return the number of days in the given Islamic year 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @draft ICU 2.4 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::handleGetYearLength(int32_t extendedYear) const { 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cType == CIVIL || cType == TBLA || 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (cType == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) { 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 354 + (civilLeapYear(extendedYear) ? 1 : 0); 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(cType == ASTRONOMICAL){ 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t month = 12*(extendedYear-1); 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (trueMonthStart(month + 12) - trueMonthStart(month)); 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int len = 0; 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int i=0; i<12; i++) 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org len += handleGetMonthLength(extendedYear, i); 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return len; 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Functions for converting from field values to milliseconds.... 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Return JD of start of given month/year 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @draft ICU 2.4 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /* useMonth */) const { 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return monthStart(eyear, month) + 1948439; 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Functions for converting from milliseconds to field values 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------------------------------------------- 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @draft ICU 2.4 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::handleGetExtendedYear() { 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t year; 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR) { 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year = internalGet(UCAL_EXTENDED_YEAR, 1); // Default to year 1 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year = internalGet(UCAL_YEAR, 1); // Default to year 1 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return year; 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Override Calendar to compute several fields specific to the Islamic 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* calendar system. These are: 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* <ul><li>ERA 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* <li>YEAR 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* <li>MONTH 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* <li>DAY_OF_MONTH 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* <li>DAY_OF_YEAR 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* <li>EXTENDED_YEAR</ul> 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* The DAY_OF_WEEK and DOW_LOCAL fields are already set when this 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* method is called. The getGregorianXxx() methods return Gregorian 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* calendar equivalents for the given Julian day. 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* @draft ICU 2.4 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org*/ 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) { 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t year, month, dayOfMonth, dayOfYear; 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDate startDate; 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t days = julianDay - CIVIL_EPOC; 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cType == CIVIL || cType == TBLA) { 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cType == TBLA) 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org days = julianDay - ASTRONOMICAL_EPOC; 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Use the civil calendar approximation, which is just arithmetic 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year = (int)ClockMath::floorDivide( (double)(30 * days + 10646) , 10631.0 ); 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 ); 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = month<11?month:11; 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org startDate = monthStart(year, month); 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(cType == ASTRONOMICAL){ 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Guess at the number of elapsed full months since the epoch 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t months = (int32_t)uprv_floor((double)days / CalendarAstronomer::SYNODIC_MONTH); 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org startDate = uprv_floor(months * CalendarAstronomer::SYNODIC_MONTH); 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double age = moonAge(internalGetTime(), status); 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ( days - startDate >= 25 && age > 0) { 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If we're near the end of the month, assume next month and search backwards 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org months++; 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Find out the last time that the new moon was actually visible at this longitude 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This returns midnight the night that the moon was visible at sunset. 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while ((startDate = trueMonthStart(months)) > days) { 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // If it was after the date in question, back up a month and try again 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org months--; 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year = months / 12 + 1; 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = months % 12; 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(cType == UMALQURA) { 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t umalquraStartdays = yearStart(UMALQURA_YEAR_START) ; 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if( days < umalquraStartdays){ 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org //Use Civil calculation 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year = (int)ClockMath::floorDivide( (double)(30 * days + 10646) , 10631.0 ); 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 ); 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = month<11?month:11; 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org startDate = monthStart(year, month); 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else{ 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int y =UMALQURA_YEAR_START-1, m =0; 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org long d = 1; 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(d > 0){ 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org y++; 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org d = days - yearStart(y) +1; 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(d == handleGetYearLength(y)){ 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org m=11; 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org }else if(d < handleGetYearLength(y) ){ 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int monthLen = handleGetMonthLength(y, m); 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org m=0; 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org while(d > monthLen){ 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org d -= monthLen; 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org m++; 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org monthLen = handleGetMonthLength(y, m); 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year = y; 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org month = m; 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { // invalid 'civil' 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(false); // should not get here, out of range 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org year=month=0; 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dayOfMonth = (days - monthStart(year, month)) + 1; 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Now figure out the day of the year. 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dayOfYear = (days - monthStart(year, 0) + 1); 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org internalSet(UCAL_ERA, 0); 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org internalSet(UCAL_YEAR, year); 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org internalSet(UCAL_EXTENDED_YEAR, year); 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org internalSet(UCAL_MONTH, month); 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org internalSet(UCAL_DAY_OF_MONTH, dayOfMonth); 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org internalSet(UCAL_DAY_OF_YEAR, dayOfYear); 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgIslamicCalendar::inDaylightTime(UErrorCode& status) const 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // copied from GregorianCalendar 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || (&(getTimeZone()) == NULL && !getTimeZone().useDaylightTime())) 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Force an update of the state of the Calendar. 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ((IslamicCalendar*)this)->complete(status); // cast away const 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (UBool)(U_SUCCESS(status) ? (internalGet(UCAL_DST_OFFSET) != 0) : FALSE); 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The system maintains a static default century start date and Year. They are 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * initialized the first time they are used. Once the system default century date 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and year are set, they do not change. 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UDate gSystemDefaultCenturyStart = DBL_MIN; 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic int32_t gSystemDefaultCenturyStartYear = -1; 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic icu::UInitOnce gSystemDefaultCenturyInit = U_INITONCE_INITIALIZER; 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool IslamicCalendar::haveDefaultCentury() const 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUDate IslamicCalendar::defaultCenturyStart() const 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // lazy-evaluate systemDefaultCenturyStart 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return gSystemDefaultCenturyStart; 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t IslamicCalendar::defaultCenturyStartYear() const 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // lazy-evaluate systemDefaultCenturyStartYear 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org umtx_initOnce(gSystemDefaultCenturyInit, &initializeSystemDefaultCentury); 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return gSystemDefaultCenturyStartYear; 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid U_CALLCONV 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgIslamicCalendar::initializeSystemDefaultCentury() 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // initialize systemDefaultCentury and systemDefaultCenturyYear based 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // on the current time. They'll be set to 80 years before 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the current time. 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org IslamicCalendar calendar(Locale("@calendar=islamic-civil"),status); 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calendar.setTime(Calendar::getNow(), status); 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org calendar.add(UCAL_YEAR, -80, status); 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gSystemDefaultCenturyStart = calendar.getTime(status); 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org gSystemDefaultCenturyStartYear = calendar.get(UCAL_YEAR, status); 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We have no recourse upon failure unless we want to propagate the failure 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // out. 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(IslamicCalendar) 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 679