/** * Override Calendar to compute several fields specific to the Islamic * calendar system. These are: * * <ul><li>ERA * <li>YEAR * <li>MONTH * <li>DAY_OF_MONTH * <li>DAY_OF_YEAR * <li>EXTENDED_YEAR</ul> * * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this * method is called. The getGregorianXxx() methods return Gregorian * calendar equivalents for the given Julian day. * @draft ICU 2.4 */ void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode & status) { int32_t year, month, dayOfMonth, dayOfYear; UDate startDate; int32_t days = julianDay - 1948440; if (civil == CIVIL) { // Use the civil calendar approximation, which is just arithmetic year = (int)ClockMath::floorDivide((double)(30 * days + 10646) , 10631.0); month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5); month = month < 11 ? month : 11; startDate = monthStart(year, month); } else { // Guess at the number of elapsed full months since the epoch int32_t months = (int32_t)uprv_floor((double)days / CalendarAstronomer::SYNODIC_MONTH); startDate = uprv_floor(months * CalendarAstronomer::SYNODIC_MONTH); double age = moonAge(internalGetTime(), status); if (U_FAILURE(status)) { status = U_MEMORY_ALLOCATION_ERROR; return; } if (days - startDate >= 25 && age > 0) { // If we're near the end of the month, assume next month and search backwards months++; } // Find out the last time that the new moon was actually visible at this longitude // This returns midnight the night that the moon was visible at sunset. while ((startDate = trueMonthStart(months)) > days) { // If it was after the date in question, back up a month and try again months--; } year = months / 12 + 1; month = months % 12; } dayOfMonth = (days - monthStart(year, month)) + 1; // Now figure out the day of the year. dayOfYear = (days - monthStart(year, 0) + 1); internalSet(UCAL_ERA, 0); internalSet(UCAL_YEAR, year); internalSet(UCAL_EXTENDED_YEAR, year); internalSet(UCAL_MONTH, month); internalSet(UCAL_DAY_OF_MONTH, dayOfMonth); internalSet(UCAL_DAY_OF_YEAR, dayOfYear); }
/** * @draft ICU 2.4 */ int32_t IslamicCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /* useMonth */) const { // This may be called by Calendar::handleComputeJulianDay with months out of the range // 0..11. Need to handle that here since monthStart requires months in the range 0.11. if (month > 11) { eyear += (month / 12); month %= 12; } else if (month < 0) { month++; eyear += (month / 12) - 1; month = (month % 12) + 11; } return monthStart(eyear, month) + ((cType == TBLA)? ASTRONOMICAL_EPOC: CIVIL_EPOC) - 1; }
/** * @draft ICU 2.4 */ int32_t IslamicCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool /* useMonth */) const { return monthStart(eyear, month) + 1948439; }
int dayTh(int year,int month,int day){ int isLeap=isLeapYear(year); int startPoint=monthStart(month,isLeap); int dayth=startPoint-1+day; return dayth; }
/** * Override Calendar to compute several fields specific to the Islamic * calendar system. These are: * * <ul><li>ERA * <li>YEAR * <li>MONTH * <li>DAY_OF_MONTH * <li>DAY_OF_YEAR * <li>EXTENDED_YEAR</ul> * * The DAY_OF_WEEK and DOW_LOCAL fields are already set when this * method is called. The getGregorianXxx() methods return Gregorian * calendar equivalents for the given Julian day. * @draft ICU 2.4 */ void IslamicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) { int32_t year, month, dayOfMonth, dayOfYear; int32_t startDate; int32_t days = julianDay - CIVIL_EPOC; if (cType == CIVIL || cType == TBLA) { if(cType == TBLA) { days = julianDay - ASTRONOMICAL_EPOC; } // Use the civil calendar approximation, which is just arithmetic year = (int)ClockMath::floorDivide( (double)(30 * days + 10646) , 10631.0 ); month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 ); month = month<11?month:11; startDate = monthStart(year, month); } else if(cType == ASTRONOMICAL){ // Guess at the number of elapsed full months since the epoch int32_t months = (int32_t)uprv_floor((double)days / CalendarAstronomer::SYNODIC_MONTH); startDate = (int32_t)uprv_floor(months * CalendarAstronomer::SYNODIC_MONTH); double age = moonAge(internalGetTime(), status); if (U_FAILURE(status)) { status = U_MEMORY_ALLOCATION_ERROR; return; } if ( days - startDate >= 25 && age > 0) { // If we're near the end of the month, assume next month and search backwards months++; } // Find out the last time that the new moon was actually visible at this longitude // This returns midnight the night that the moon was visible at sunset. while ((startDate = trueMonthStart(months)) > days) { // If it was after the date in question, back up a month and try again months--; } year = months / 12 + 1; month = months % 12; } else if(cType == UMALQURA) { int32_t umalquraStartdays = yearStart(UMALQURA_YEAR_START) ; if( days < umalquraStartdays){ //Use Civil calculation year = (int)ClockMath::floorDivide( (double)(30 * days + 10646) , 10631.0 ); month = (int32_t)uprv_ceil((days - 29 - yearStart(year)) / 29.5 ); month = month<11?month:11; startDate = monthStart(year, month); }else{ int y =UMALQURA_YEAR_START-1, m =0; long d = 1; while(d > 0){ y++; d = days - yearStart(y) +1; if(d == handleGetYearLength(y)){ m=11; break; }else if(d < handleGetYearLength(y) ){ int monthLen = handleGetMonthLength(y, m); m=0; while(d > monthLen){ d -= monthLen; m++; monthLen = handleGetMonthLength(y, m); } break; } } year = y; month = m; } } else { // invalid 'civil' U_ASSERT(false); // should not get here, out of range year=month=0; } dayOfMonth = (days - monthStart(year, month)) + 1; // Now figure out the day of the year. dayOfYear = (days - monthStart(year, 0)) + 1; internalSet(UCAL_ERA, 0); internalSet(UCAL_YEAR, year); internalSet(UCAL_EXTENDED_YEAR, year); internalSet(UCAL_MONTH, month); internalSet(UCAL_DAY_OF_MONTH, dayOfMonth); internalSet(UCAL_DAY_OF_YEAR, dayOfYear); }