Example #1
0
/**
 * Return the Julian day number of day before the first day of the
 * given month in the given extended year.
 *
 * <p>Note: This method reads the IS_LEAP_MONTH field to determine
 * whether the given month is a leap month.
 * @param eyear the extended year
 * @param month the zero-based month.  The month is also determined
 * by reading the IS_LEAP_MONTH field.
 * @return the Julian day number of the day before the first
 * day of the given month and year
 * @stable ICU 2.8
 */
int32_t ChineseCalendar::handleComputeMonthStart(int32_t eyear, int32_t month, UBool useMonth) const {

    ChineseCalendar *nonConstThis = (ChineseCalendar*)this; // cast away const

    // If the month is out of range, adjust it into range, and
    // modify the extended year value accordingly.
    if (month < 0 || month > 11) {
        double m = month;
        eyear += (int32_t)ClockMath::floorDivide(m, 12.0, m);
        month = (int32_t)m;
    }

    int32_t gyear = eyear + fEpochYear - 1; // Gregorian year
    int32_t theNewYear = newYear(gyear);
    int32_t newMoon = newMoonNear(theNewYear + month * 29, TRUE);

    int32_t julianDay = newMoon + kEpochStartAsJulianDay;

    // Save fields for later restoration
    int32_t saveMonth = internalGet(UCAL_MONTH);
    int32_t saveIsLeapMonth = internalGet(UCAL_IS_LEAP_MONTH);

    // Ignore IS_LEAP_MONTH field if useMonth is false
    int32_t isLeapMonth = useMonth ? saveIsLeapMonth : 0;

    UErrorCode status = U_ZERO_ERROR;
    nonConstThis->computeGregorianFields(julianDay, status);
    if (U_FAILURE(status))
        return 0;

    // This will modify the MONTH and IS_LEAP_MONTH fields (only)
    nonConstThis->computeChineseFields(newMoon, getGregorianYear(),
                         getGregorianMonth(), FALSE);

    if (month != internalGet(UCAL_MONTH) ||
        isLeapMonth != internalGet(UCAL_IS_LEAP_MONTH)) {
        newMoon = newMoonNear(newMoon + SYNODIC_GAP, TRUE);
        julianDay = newMoon + kEpochStartAsJulianDay;
    }

    nonConstThis->internalSet(UCAL_MONTH, saveMonth);
    nonConstThis->internalSet(UCAL_IS_LEAP_MONTH, saveIsLeapMonth);

    return julianDay - 1;
}
Example #2
0
/**
 * Override Calendar to compute several fields specific to the Chinese
 * 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.
 *
 * <p>Compute the ChineseCalendar-specific field IS_LEAP_MONTH.
 * @stable ICU 2.8
 */
void ChineseCalendar::handleComputeFields(int32_t julianDay, UErrorCode &/*status*/) {

    computeChineseFields(julianDay - kEpochStartAsJulianDay, // local days
                         getGregorianYear(), getGregorianMonth(),
                         TRUE); // set all fields
}
Example #3
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);
}