Пример #1
0
void TaiwanCalendar::timeToFields(UDate theTime, UBool quick, UErrorCode & status)
{
	//Calendar::timeToFields(theTime, quick, status);

	int32_t era = internalGet(UCAL_ERA);
	int32_t year = internalGet(UCAL_YEAR);

	if (era == GregorianCalendar::BC)
	{
		year = 1 - year;
		era = TaiwanCalendar::MINGUO;
	}
	else if (era == GregorianCalendar::AD)
	{
		era = TaiwanCalendar::MINGUO;
	}
	else
	{
		status = U_INTERNAL_PROGRAM_ERROR;
	}

	year = year - kTaiwanEraStart;

	internalSet(UCAL_ERA, era);
	internalSet(UCAL_YEAR, year);
}
Пример #2
0
void BuddhistCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
{
    GregorianCalendar::handleComputeFields(julianDay, status);
    int32_t y = internalGet(UCAL_EXTENDED_YEAR) - kBuddhistEraStart;
    internalSet(UCAL_ERA, 0);
    internalSet(UCAL_YEAR, y);
}
Пример #3
0
void TaiwanCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status)
{
    GregorianCalendar::handleComputeFields(julianDay, status);
    int32_t y = internalGet(UCAL_EXTENDED_YEAR) - kTaiwanEraStart;
    if(y>0) {
        internalSet(UCAL_ERA, MINGUO);
        internalSet(UCAL_YEAR, y);
    } else {
        internalSet(UCAL_ERA, BEFORE_MINGUO);
        internalSet(UCAL_YEAR, 1-y);
    }
}
Пример #4
0
void
EthiopicCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/)
{
    int32_t eyear, month, day, era, year;
    jdToCE(julianDay, getJDEpochOffset(), eyear, month, day);

    if (isAmeteAlemEra()) {
        era = AMETE_ALEM;
        year = eyear + AMETE_MIHRET_DELTA;
    } else {
        if (eyear > 0) {
            era = AMETE_MIHRET;
            year = eyear;
        } else {
            era = AMETE_ALEM;
            year = eyear + AMETE_MIHRET_DELTA;
        }
    }

    internalSet(UCAL_EXTENDED_YEAR, eyear);
    internalSet(UCAL_ERA, era);
    internalSet(UCAL_YEAR, year);
    internalSet(UCAL_MONTH, month);
    internalSet(UCAL_DATE, day);
    internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
}
Пример #5
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);
}
Пример #6
0
void PersianCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) {
    int jy,jm,jd;        
    julian_to_jalali(julianDay-1947955,&jy,&jm,&jd);
    internalSet(UCAL_ERA, 0);
    internalSet(UCAL_YEAR, jy);
    internalSet(UCAL_EXTENDED_YEAR, jy);
    internalSet(UCAL_MONTH, jm-1);
    internalSet(UCAL_DAY_OF_MONTH, jd);
    internalSet(UCAL_DAY_OF_YEAR, jd + MONTH_COUNT[jm-1][2]);
}    
Пример #7
0
/**
* Subclasses may override this method to compute several fields
* specific to each calendar system.  These are:
*
* <ul><li>ERA
* <li>YEAR
* <li>MONTH
* <li>DAY_OF_MONTH
* <li>DAY_OF_YEAR
* <li>EXTENDED_YEAR</ul>
* 
* Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields,
* which will be set when this method is called.  Subclasses can
* also call the getGregorianXxx() methods to obtain Gregorian
* calendar equivalents for the given Julian day.
*
* <p>In addition, subclasses should compute any subclass-specific
* fields, that is, fields from BASE_FIELD_COUNT to
* getFieldCount() - 1.
* @internal
*/
void HebrewCalendar::handleComputeFields(int32_t julianDay, UErrorCode &status) {
    int32_t d = julianDay - 347997;
    double m = ((d * (double)DAY_PARTS)/ (double) MONTH_PARTS);         // Months (approx)
    int32_t year = (int32_t)( ((19. * m + 234.) / 235.) + 1.);     // Years (approx)
    int32_t ys  = startOfYear(year, status);                   // 1st day of year
    int32_t dayOfYear = (d - ys);

    // Because of the postponement rules, it's possible to guess wrong.  Fix it.
    while (dayOfYear < 1) {
        year--;
        ys  = startOfYear(year, status);
        dayOfYear = (d - ys);
    }

    // Now figure out which month we're in, and the date within that month
    int32_t type = yearType(year);
    UBool isLeap = isLeapYear(year);

    int32_t month = 0;
    int32_t momax = UPRV_LENGTHOF(MONTH_START);
    while (month < momax && dayOfYear > (  isLeap ? LEAP_MONTH_START[month][type] : MONTH_START[month][type] ) ) {
        month++;
    }
    if (month >= momax || month<=0) {
        // TODO: I found dayOfYear could be out of range when
        // a large value is set to julianDay.  I patched startOfYear
        // to reduce the chace, but it could be still reproduced either
        // by startOfYear or other places.  For now, we check
        // the month is in valid range to avoid out of array index
        // access problem here.  However, we need to carefully review
        // the calendar implementation to check the extreme limit of
        // each calendar field and the code works well for any values
        // in the valid value range.  -yoshito
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return;
    }
    month--;
    int dayOfMonth = dayOfYear - (isLeap ? LEAP_MONTH_START[month][type] : MONTH_START[month][type]);

    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);       
}
Пример #8
0
/*
 * Override Calendar to compute several fields specific to the Indian
 * calendar system.  These are:
 *
 * <ul><li>ERA
 * <li>YEAR
 * <li>MONTH
 * <li>DAY_OF_MONTH
 * <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.
 */
void IndianCalendar::handleComputeFields(int32_t julianDay, UErrorCode&  /* status */) {
    double jdAtStartOfGregYear;
    int32_t leapMonth, IndianYear, yday, IndianMonth, IndianDayOfMonth, mday;
    int32_t gregorianYear;      // Stores gregorian date corresponding to Julian day;
    int32_t gd[3];

    gregorianYear = jdToGregorian(julianDay, gd)[0];          // Gregorian date for Julian day
    IndianYear = gregorianYear - INDIAN_ERA_START;            // Year in Saka era
    jdAtStartOfGregYear = gregorianToJD(gregorianYear, 1, 1); // JD at start of Gregorian year
    yday = (int32_t)(julianDay - jdAtStartOfGregYear);        // Day number in Gregorian year (starting from 0)

    if (yday < INDIAN_YEAR_START) {
        // Day is at the end of the preceding Saka year
        IndianYear -= 1;
        leapMonth = isGregorianLeap(gregorianYear - 1) ? 31 : 30; // Days in leapMonth this year, previous Gregorian year
        yday += leapMonth + (31 * 5) + (30 * 3) + 10;
    } else {
        leapMonth = isGregorianLeap(gregorianYear) ? 31 : 30; // Days in leapMonth this year
        yday -= INDIAN_YEAR_START;
    }

    if (yday < leapMonth) {
        IndianMonth = 0;
        IndianDayOfMonth = yday + 1;
    } else {
        mday = yday - leapMonth;
        if (mday < (31 * 5)) {
            IndianMonth = (int32_t)uprv_floor(mday / 31) + 1;
            IndianDayOfMonth = (mday % 31) + 1;
        } else {
            mday -= 31 * 5;
            IndianMonth = (int32_t)uprv_floor(mday / 30) + 6;
            IndianDayOfMonth = (mday % 30) + 1;
        }
   }

   internalSet(UCAL_ERA, 0);
   internalSet(UCAL_EXTENDED_YEAR, IndianYear);
   internalSet(UCAL_YEAR, IndianYear);
   internalSet(UCAL_MONTH, IndianMonth);
   internalSet(UCAL_DAY_OF_MONTH, IndianDayOfMonth);
   internalSet(UCAL_DAY_OF_YEAR, yday + 1); // yday is 0-based
}
Пример #9
0
void
CopticCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/)
{
    int32_t eyear, month, day, era, year;
    jdToCE(julianDay, getJDEpochOffset(), eyear, month, day);

    if (eyear <= 0) {
        era = BCE;
        year = 1 - eyear;
    } else {
        era = CE;
        year = eyear;
    }

    internalSet(UCAL_EXTENDED_YEAR, eyear);
    internalSet(UCAL_ERA, era);
    internalSet(UCAL_YEAR, year);
    internalSet(UCAL_MONTH, month);
    internalSet(UCAL_DATE, day);
    internalSet(UCAL_DAY_OF_YEAR, (30 * month) + day);
}
Пример #10
0
/**
 * Override Calendar to compute several fields specific to the Persian
 * 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.
 */
void PersianCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) {
    int32_t year, month, dayOfMonth, dayOfYear;

    int32_t daysSinceEpoch = julianDay - PERSIAN_EPOCH;
    year = 1 + ClockMath::floorDivide(33 * daysSinceEpoch + 3, 12053);

    int32_t farvardin1 = 365 * (year - 1) + ClockMath::floorDivide(8 * year + 21, 33);
    dayOfYear = (daysSinceEpoch - farvardin1); // 0-based
    if (dayOfYear < 216) { // Compute 0-based month
        month = dayOfYear / 31;
    } else {
        month = (dayOfYear - 6) / 30;
    }
    dayOfMonth = dayOfYear - kPersianNumDays[month] + 1;
    ++dayOfYear; // Make it 1-based now

    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);
}    
Пример #11
0
void JapaneseCalendar::handleComputeFields(int32_t julianDay, UErrorCode & status)
{
    //Calendar::timeToFields(theTime, quick, status);
    GregorianCalendar::handleComputeFields(julianDay, status);
    int32_t year = internalGet(UCAL_EXTENDED_YEAR); // Gregorian year

    int32_t low = 0;

    // Short circuit for recent years.  Most modern computations will
    // occur in the current era and won't require the binary search.
    // Note that if the year is == the current era year, then we use
    // the binary search to handle the month/dom comparison.
#ifdef U_DEBUG_JCAL
    fprintf(stderr, "==  %d \n", year);
#endif

    if (year > kEraInfo[kCurrentEra].year)
    {
        low = kCurrentEra;
#ifdef U_DEBUG_JCAL
        fprintf(stderr, " low=%d (special)\n", low);
#endif
    }
    else
    {
        // Binary search
        int32_t high = kEraCount;

#ifdef U_DEBUG_JCAL
        fprintf(stderr, " high=%d\n", high);
#endif
        while (low < high - 1)
        {
            int32_t i = (low + high) / 2;
            int32_t diff = year - kEraInfo[i].year;

#ifdef U_DEBUG_JCAL
            fprintf(stderr, "  d=%d   low=%d, high=%d. Considering %d:M%d D%d Y%d. { we are ?:M%d D%d Y%d }\n",
                    diff, low, high, i, kEraInfo[i].month - 1, kEraInfo[i].day,  kEraInfo[i].year, internalGet(UCAL_MONTH),
                    internalGet(UCAL_DATE), year);
#endif

            // If years are the same, then compare the months, and if those
            // are the same, compare days of month.  In the ERAS array
            // months are 1-based for easier maintenance.
            if (diff == 0)
            {
                diff = internalGet(UCAL_MONTH) - (kEraInfo[i].month - 1);
#ifdef U_DEBUG_JCAL
                fprintf(stderr, "diff now %d (M)  = %d - %d - 1\n", diff, internalGet(UCAL_MONTH), kEraInfo[i].month);
#endif
                if (diff == 0)
                {
                    diff = internalGet(UCAL_DATE) - kEraInfo[i].day;
#ifdef U_DEBUG_JCAL
                    fprintf(stderr, "diff now %d (D)\n", diff);
#endif
                }
            }
            if (diff >= 0)
            {
                low = i;
            }
            else
            {
                high = i;
            }
#ifdef U_DEBUG_JCAL
            fprintf(stderr, ". low=%d, high=%d, i=%d, diff=%d.. %d\n", low, high, i, diff, year);
#endif

        }
    }

#ifdef U_DEBUG_JCAL
    fprintf(stderr, "  low[era]=%d,.. %d\n", low, year);
#endif
    // Now we've found the last era that starts before this date, so
    // adjust the year to count from the start of that era.  Note that
    // all dates before the first era will fall into the first era by
    // the algorithm.

    internalSet(UCAL_ERA, low);
    internalSet(UCAL_YEAR, year - kEraInfo[low].year + 1);
#ifdef U_DEBUG_JCAL
    fprintf(stderr, "  Set ERA=%d, year=%d\n", low, year - kEraInfo[low].year + 1);
#endif

}
Пример #12
0
 void set(const T & t) {
 	if (type() == dsIn)
 		internalSet( (void*)(&t) );
 	else
 		throw "Output ports can't receive data!";
 }
Пример #13
0
 void set(const T & t) {
 	if (type() == dsIn)
 		internalSet( (void*)(&t) );
 	else
 		throw std::runtime_error("DataStreamInterface: Output ports can't receive data!");
 }
Пример #14
0
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv)
{
   internalSet(handle, fv);
}
Пример #15
0
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4I& fv)
{
   internalSet(handle, fv);
}
Пример #16
0
/**
 * Compute fields for the Chinese calendar system.  This method can
 * either set all relevant fields, as required by
 * <code>handleComputeFields()</code>, or it can just set the MONTH and
 * IS_LEAP_MONTH fields, as required by
 * <code>handleComputeMonthStart()</code>.
 *
 * <p>As a side effect, this method sets {@link #isLeapYear}.
 * @param days days after January 1, 1970 0:00 astronomical base zone
 * of the date to compute fields for
 * @param gyear the Gregorian year of the given date
 * @param gmonth the Gregorian month of the given date
 * @param setAllFields if true, set the EXTENDED_YEAR, ERA, YEAR,
 * DAY_OF_MONTH, and DAY_OF_YEAR fields.  In either case set the MONTH
 * and IS_LEAP_MONTH fields.
 */
void ChineseCalendar::computeChineseFields(int32_t days, int32_t gyear, int32_t gmonth,
                                  UBool setAllFields) {

    // Find the winter solstices before and after the target date.
    // These define the boundaries of this Chinese year, specifically,
    // the position of month 11, which always contains the solstice.
    // We want solsticeBefore <= date < solsticeAfter.
    int32_t solsticeBefore;
    int32_t solsticeAfter = winterSolstice(gyear);
    if (days < solsticeAfter) {
        solsticeBefore = winterSolstice(gyear - 1);
    } else {
        solsticeBefore = solsticeAfter;
        solsticeAfter = winterSolstice(gyear + 1);
    }

    // Find the start of the month after month 11.  This will be either
    // the prior month 12 or leap month 11 (very rare).  Also find the
    // start of the following month 11.
    int32_t firstMoon = newMoonNear(solsticeBefore + 1, TRUE);
    int32_t lastMoon = newMoonNear(solsticeAfter + 1, FALSE);
    int32_t thisMoon = newMoonNear(days + 1, FALSE); // Start of this month
    // Note: isLeapYear is a member variable
    isLeapYear = synodicMonthsBetween(firstMoon, lastMoon) == 12;

    int32_t month = synodicMonthsBetween(firstMoon, thisMoon);
    if (isLeapYear && isLeapMonthBetween(firstMoon, thisMoon)) {
        month--;
    }
    if (month < 1) {
        month += 12;
    }

    UBool isLeapMonth = isLeapYear &&
        hasNoMajorSolarTerm(thisMoon) &&
        !isLeapMonthBetween(firstMoon, newMoonNear(thisMoon - SYNODIC_GAP, FALSE));

    internalSet(UCAL_MONTH, month-1); // Convert from 1-based to 0-based
    internalSet(UCAL_IS_LEAP_MONTH, isLeapMonth?1:0);

    if (setAllFields) {

        // Extended year and cycle year is based on the epoch year

        int32_t extended_year = gyear - fEpochYear;
        int cycle_year = gyear - CHINESE_EPOCH_YEAR;
        if (month < 11 ||
            gmonth >= UCAL_JULY) {
            extended_year++;
            cycle_year++;
        }
        int32_t dayOfMonth = days - thisMoon + 1;

        internalSet(UCAL_EXTENDED_YEAR, extended_year);

        // 0->0,60  1->1,1  60->1,60  61->2,1  etc.
        int32_t yearOfCycle;
        int32_t cycle = ClockMath::floorDivide(cycle_year - 1, 60, yearOfCycle);
        internalSet(UCAL_ERA, cycle + 1);
        internalSet(UCAL_YEAR, yearOfCycle + 1);

        internalSet(UCAL_DAY_OF_MONTH, dayOfMonth);

        // Days will be before the first new year we compute if this
        // date is in month 11, leap 11, 12.  There is never a leap 12.
        // New year computations are cached so this should be cheap in
        // the long run.
        int32_t theNewYear = newYear(gyear);
        if (days < theNewYear) {
            theNewYear = newYear(gyear-1);
        }
        internalSet(UCAL_DAY_OF_YEAR, days - theNewYear + 1);
    }
}
Пример #17
0
void GregorianCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status) {
    int32_t eyear, month, dayOfMonth, dayOfYear, unusedRemainder;


    if(U_FAILURE(status)) { 
        return; 
    }

#if defined (U_DEBUG_CAL)
    fprintf(stderr, "%s:%d: jd%d- (greg's %d)- [cut=%d]\n", 
        __FILE__, __LINE__, julianDay, getGregorianDayOfYear(), fCutoverJulianDay);
#endif


    if (julianDay >= fCutoverJulianDay) {
        month = getGregorianMonth();
        dayOfMonth = getGregorianDayOfMonth();
        dayOfYear = getGregorianDayOfYear();
        eyear = getGregorianYear();
    } else {
        // The Julian epoch day (not the same as Julian Day)
        // is zero on Saturday December 30, 0 (Gregorian).
        int32_t julianEpochDay = julianDay - (kJan1_1JulianDay - 2);
		eyear = (int32_t) ClockMath::floorDivide((4.0*julianEpochDay) + 1464.0, (int32_t) 1461, unusedRemainder);

        // Compute the Julian calendar day number for January 1, eyear
        int32_t january1 = 365*(eyear-1) + ClockMath::floorDivide(eyear-1, (int32_t)4);
        dayOfYear = (julianEpochDay - january1); // 0-based

        // Julian leap years occurred historically every 4 years starting
        // with 8 AD.  Before 8 AD the spacing is irregular; every 3 years
        // from 45 BC to 9 BC, and then none until 8 AD.  However, we don't
        // implement this historical detail; instead, we implement the
        // computatinally cleaner proleptic calendar, which assumes
        // consistent 4-year cycles throughout time.
        UBool isLeap = ((eyear&0x3) == 0); // equiv. to (eyear%4 == 0)

        // Common Julian/Gregorian calculation
        int32_t correction = 0;
        int32_t march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
        if (dayOfYear >= march1) {
            correction = isLeap ? 1 : 2;
        }
        month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month
        dayOfMonth = dayOfYear - (isLeap?kLeapNumDays[month]:kNumDays[month]) + 1; // one-based DOM
        ++dayOfYear;
#if defined (U_DEBUG_CAL)
        //     fprintf(stderr, "%d - %d[%d] + 1\n", dayOfYear, isLeap?kLeapNumDays[month]:kNumDays[month], month );
        //           fprintf(stderr, "%s:%d:  greg's HCF %d -> %d/%d/%d not %d/%d/%d\n", 
        //                   __FILE__, __LINE__,julianDay,
        //          eyear,month,dayOfMonth,
        //          getGregorianYear(), getGregorianMonth(), getGregorianDayOfMonth()  );
        fprintf(stderr, "%s:%d: doy %d (greg's %d)- [cut=%d]\n", 
            __FILE__, __LINE__, dayOfYear, getGregorianDayOfYear(), fCutoverJulianDay);
#endif

    }

    // [j81] if we are after the cutover in its year, shift the day of the year
    if((eyear == fGregorianCutoverYear) && (julianDay >= fCutoverJulianDay)) {
        //from handleComputeMonthStart
        int32_t gregShift = Grego::gregorianShift(eyear);
#if defined (U_DEBUG_CAL)
        fprintf(stderr, "%s:%d:  gregorian shift %d :::  doy%d => %d [cut=%d]\n",
            __FILE__, __LINE__,gregShift, dayOfYear, dayOfYear+gregShift, fCutoverJulianDay);
#endif
        dayOfYear += gregShift;
    }

    internalSet(UCAL_MONTH, month);
    internalSet(UCAL_DAY_OF_MONTH, dayOfMonth);
    internalSet(UCAL_DAY_OF_YEAR, dayOfYear);
    internalSet(UCAL_EXTENDED_YEAR, eyear);
    int32_t era = AD;
    if (eyear < 1) {
        era = BC;
        eyear = 1 - eyear;
    }
    internalSet(UCAL_ERA, era);
    internalSet(UCAL_YEAR, eyear);
}
Пример #18
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);       
}