Example #1
0
/**
 * Return the number of days in the given Islamic year
 * @draft ICU 2.4
 */
int32_t IslamicCalendar::handleGetYearLength(int32_t extendedYear) const {
  if (civil == CIVIL) {
    return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
  } else {
    int32_t month = 12*(extendedYear-1);
    return (trueMonthStart(month + 12) - trueMonthStart(month));
  }
}
/**
* Return the number of days in the given Islamic year
* @draft ICU 2.4
*/
int32_t IslamicCalendar::handleGetYearLength(int32_t extendedYear) const {
    if (cType == CIVIL || cType == TBLA ||
        (cType == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) {
        return 354 + (civilLeapYear(extendedYear) ? 1 : 0);
    } else if(cType == ASTRONOMICAL){
        int32_t month = 12*(extendedYear-1);
        return (trueMonthStart(month + 12) - trueMonthStart(month));
    } else {
        int len = 0;
        for(int i=0; i<12; i++)
            len += handleGetMonthLength(extendedYear, i);
        return len;
    }
}
Example #3
0
/**
 * Return the length (in days) of the given month.
 *
 * @param year  The hijri year
 * @param year  The hijri month, 0-based
 * @draft ICU 2.4
 */
int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {

  int32_t length = 0;
        
  if (civil == CIVIL) {
    length = 29 + (month+1) % 2;
    if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
      length++;
    }
  } else {
    month = 12*(extendedYear-1) + month;
    length =  trueMonthStart(month+1) - trueMonthStart(month) ;
  }
  return length;
}
Example #4
0
/**
 * Return the day # on which the given year starts.  Days are counted
 * from the Hijri epoch, origin 0.
 */
int32_t IslamicCalendar::yearStart(int32_t year) {
  if (civil == CIVIL) {
    return (year-1)*354 + Math::floorDivide((3+11*year),30);
  } else {
    return trueMonthStart(12*(year-1));
  }
}
Example #5
0
/**
 * Return the day # on which the given month starts.  Days are counted
 * from the Hijri epoch, origin 0.
 *
 * @param year  The hijri year
 * @param year  The hijri month, 0-based
 */
int32_t IslamicCalendar::monthStart(int32_t year, int32_t month) const {
  if (civil == CIVIL) {
    return (int32_t)uprv_ceil(29.5*month)
      + (year-1)*354 + (int32_t)Math::floorDivide((3+11*year),30);
  } else {
    return trueMonthStart(12*(year-1) + month);
  }
}
Example #6
0
/**
* Return the length (in days) of the given month.
*
* @param year  The hijri year
* @param year  The hijri month, 0-based
* @draft ICU 2.4
*/
int32_t IslamicCalendar::handleGetMonthLength(int32_t extendedYear, int32_t month) const {

    int32_t length = 0;

    if (cType == CIVIL || cType == TBLA ||
        (cType == UMALQURA && (extendedYear<UMALQURA_YEAR_START || extendedYear>UMALQURA_YEAR_END)) ) {
        length = 29 + (month+1) % 2;
        if (month == DHU_AL_HIJJAH && civilLeapYear(extendedYear)) {
            length++;
        }
    } else if(cType == ASTRONOMICAL){
        month = 12*(extendedYear-1) + month;
        length =  trueMonthStart(month+1) - trueMonthStart(month) ;
    } else {
        length = getUmalqura_MonthLength(extendedYear - UMALQURA_YEAR_START, month);
    }
    return length;
}
Example #7
0
/**
* 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);
}
/**
* Return the day # on which the given month starts.  Days are counted
* from the Hijri epoch, origin 0.
*
* @param year  The hijri year
* @param year  The hijri month, 0-based
*/
int32_t IslamicCalendar::monthStart(int32_t year, int32_t month) const {
    if (cType == CIVIL || cType == TBLA) {
        return (int32_t)uprv_ceil(29.5*month)
            + (year-1)*354 + (int32_t)ClockMath::floorDivide((3+11*year),30);
    } else if(cType==ASTRONOMICAL){
        return trueMonthStart(12*(year-1) + month);
    } else {
        int32_t ms = yearStart(year);
        for(int i=0; i< month; i++){
            ms+= handleGetMonthLength(year, i);
        }
        return ms;
    }
}
Example #9
0
/**
* Return the day # on which the given year starts.  Days are counted
* from the Hijri epoch, origin 0.
*/
int32_t IslamicCalendar::yearStart(int32_t year) const{
    if (cType == CIVIL || cType == TBLA ||
        (cType == UMALQURA && (year < UMALQURA_YEAR_START || year > UMALQURA_YEAR_END))) 
    {
        return (year-1)*354 + ClockMath::floorDivide((3+11*year),30);
    } else if(cType==ASTRONOMICAL){
        return trueMonthStart(12*(year-1));
    } else {
        year -= UMALQURA_YEAR_START;
        // rounded least-squares fit of the dates previously calculated from UMALQURA_MONTHLENGTH iteration
        int32_t yrStartLinearEstimate = (int32_t)((354.36720 * (double)year) + 460322.05 + 0.5);
        // need a slight correction to some
        return yrStartLinearEstimate + umAlQuraYrStartEstimateFix[year];
    }
}
/**
* Return the day # on which the given year starts.  Days are counted
* from the Hijri epoch, origin 0.
*/
int32_t IslamicCalendar::yearStart(int32_t year) const{
    if (cType == CIVIL || cType == TBLA ||
        (cType == UMALQURA && year < UMALQURA_YEAR_START))
    {
        return (year-1)*354 + ClockMath::floorDivide((3+11*year),30);
    } else if(cType==ASTRONOMICAL){
        return trueMonthStart(12*(year-1));
    } else {
        int32_t ys = yearStart(UMALQURA_YEAR_START-1);
        ys+= handleGetYearLength(UMALQURA_YEAR_START-1);
        for(int i=UMALQURA_YEAR_START; i< year; i++){
            ys+= handleGetYearLength(i);
        }
        return ys;
    }
}
Example #11
0
/**
* 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);       
}