Logo Search packages:      
Sourcecode: icu version File versions

UnicodeString & DateIntervalFormat::format ( Calendar fromCalendar,
Calendar toCalendar,
UnicodeString appendTo,
FieldPosition fieldPosition,
UErrorCode status 
) const

Format 2 Calendars to produce a string.

Note: "fromCalendar" and "toCalendar" are not const, since calendar is not const in SimpleDateFormat::format(Calendar&),

Parameters:
fromCalendar calendar set to the from date in date interval to be formatted into date interval string
toCalendar calendar set to the to date in date interval to be formatted into date interval string
appendTo Output parameter to receive result. Result is appended to existing contents.
fieldPosition On input: an alignment field, if desired. On output: the offsets of the alignment field.
status Output param filled with success/failure status. Caller needs to make sure it is SUCCESS at the function entrance
Returns:
Reference to 'appendTo' parameter. ICU 4.0

Definition at line 275 of file dtitvfmt.cpp.

References SimpleDateFormat::applyPattern(), DateIntervalInfo::calendarFieldToIntervalIndex(), fallbackFormat(), fDateFormat, SimpleDateFormat::format(), Calendar::get(), Calendar::getType(), Calendar::isEquivalentTo(), SimpleDateFormat::isFieldUnitIgnored(), SimpleDateFormat::toPattern(), U_FAILURE, U_ILLEGAL_ARGUMENT_ERROR, UCAL_AM_PM, UCAL_DATE, UCAL_ERA, UCAL_FIELD_COUNT, UCAL_HOUR, UCAL_MINUTE, UCAL_MONTH, and UCAL_YEAR.

                                                     {
    if ( U_FAILURE(status) ) {
        return appendTo;
    }

    // not support different calendar types and time zones
    //if ( fromCalendar.getType() != toCalendar.getType() ) {
    if ( !fromCalendar.isEquivalentTo(toCalendar) ||
         uprv_strcmp(fromCalendar.getType(), "gregorian") ) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return appendTo;
    }

    // First, find the largest different calendar field.
    UCalendarDateFields field = UCAL_FIELD_COUNT;

    if ( fromCalendar.get(UCAL_ERA,status) != toCalendar.get(UCAL_ERA,status)) {
        field = UCAL_ERA;
    } else if ( fromCalendar.get(UCAL_YEAR, status) != 
                toCalendar.get(UCAL_YEAR, status) ) {
        field = UCAL_YEAR;
    } else if ( fromCalendar.get(UCAL_MONTH, status) !=
                toCalendar.get(UCAL_MONTH, status) ) {
        field = UCAL_MONTH;
    } else if ( fromCalendar.get(UCAL_DATE, status) !=
                toCalendar.get(UCAL_DATE, status) ) {
        field = UCAL_DATE;
    } else if ( fromCalendar.get(UCAL_AM_PM, status) !=
                toCalendar.get(UCAL_AM_PM, status) ) {
        field = UCAL_AM_PM;
    } else if ( fromCalendar.get(UCAL_HOUR, status) !=
                toCalendar.get(UCAL_HOUR, status) ) {
        field = UCAL_HOUR;
    } else if ( fromCalendar.get(UCAL_MINUTE, status) !=
                toCalendar.get(UCAL_MINUTE, status) ) {
        field = UCAL_MINUTE;
    }

    if ( U_FAILURE(status) ) {
        return appendTo;
    }
    if ( field == UCAL_FIELD_COUNT ) {
        /* ignore the second/millisecond etc. small fields' difference.
         * use single date when all the above are the same.
         */
        return fDateFormat->format(fromCalendar, appendTo, pos);
    }
    
    // following call should not set wrong status,
    // all the pass-in fields are valid till here
    int32_t itvPtnIndex = DateIntervalInfo::calendarFieldToIntervalIndex(field,
                                                                        status);
    const PatternInfo& intervalPattern = fIntervalPatterns[itvPtnIndex];

    if ( intervalPattern.firstPart.isEmpty() &&
         intervalPattern.secondPart.isEmpty() ) {
        if ( fDateFormat->isFieldUnitIgnored(field) ) {
            /* the largest different calendar field is small than
             * the smallest calendar field in pattern,
             * return single date format.
             */
            return fDateFormat->format(fromCalendar, appendTo, pos);
        }
        return fallbackFormat(fromCalendar, toCalendar, appendTo, pos, status);
    }
    // If the first part in interval pattern is empty, 
    // the 2nd part of it saves the full-pattern used in fall-back.
    // For a 'real' interval pattern, the first part will never be empty.
    if ( intervalPattern.firstPart.isEmpty() ) {
        // fall back
        UnicodeString originalPattern;
        fDateFormat->toPattern(originalPattern);
        fDateFormat->applyPattern(intervalPattern.secondPart);
        appendTo = fallbackFormat(fromCalendar, toCalendar, appendTo, pos, status);
        fDateFormat->applyPattern(originalPattern);
        return appendTo;
    }
    Calendar* firstCal;
    Calendar* secondCal;
    if ( intervalPattern.laterDateFirst ) {
        firstCal = &toCalendar;
        secondCal = &fromCalendar;
    } else {
        firstCal = &fromCalendar;
        secondCal = &toCalendar;
    }
    // break the interval pattern into 2 parts,
    // first part should not be empty, 
    UnicodeString originalPattern;
    fDateFormat->toPattern(originalPattern);
    fDateFormat->applyPattern(intervalPattern.firstPart);
    fDateFormat->format(*firstCal, appendTo, pos);
    if ( !intervalPattern.secondPart.isEmpty() ) {
        fDateFormat->applyPattern(intervalPattern.secondPart);
        fDateFormat->format(*secondCal, appendTo, pos);
    }
    fDateFormat->applyPattern(originalPattern);
    return appendTo;
}


Generated by  Doxygen 1.6.0   Back to index