Ejemplo n.º 1
0
Boolean CFCalendarGetTimeRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit, CFAbsoluteTime at, CFAbsoluteTime *startp, CFTimeInterval *tip) {
    CF_OBJC_FUNCDISPATCH4(CFCalendarGetTypeID(), Boolean, calendar, "_rangeOfUnit:startTime:interval:forAT:", unit, startp, tip, at);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (kCFCalendarUnitWeekdayOrdinal == unit) return false;
    if (kCFCalendarUnitWeekday == unit) unit = kCFCalendarUnitDay;
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
        ucal_clear(calendar->_cal);
        __CFCalendarSetToFirstInstant(calendar, unit, at);
        UErrorCode status = U_ZERO_ERROR;
        UDate start = ucal_getMillis(calendar->_cal, &status);
	UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit);
	ucal_add(calendar->_cal, field, 1, &status);
        UDate end = ucal_getMillis(calendar->_cal, &status);
	if (end == start && kCFCalendarUnitEra == unit) {
            // ICU refuses to do the addition, probably because we are
            // at the limit of UCAL_ERA.  Use alternate strategy.
            CFIndex limit = ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_MAXIMUM, &status);
            if (100000 < limit) limit = 100000;
            ucal_add(calendar->_cal, UCAL_YEAR, limit, &status);
	    end = ucal_getMillis(calendar->_cal, &status);
	}
	if (U_SUCCESS(status)) {
	    if (startp) *startp = (double)start / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
	    if (tip) *tip = (double)(end - start) / 1000.0;
	    return true;
	}
    }

    return false;
}
Ejemplo n.º 2
0
CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
    CFIndex result = kCFNotFound;
    if (!__validUnits(smallerUnit, biggerUnit)) return result;
    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFIndex, calendar, "_ordinalityOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) {
	    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	    ucal_setMillis(calendar->_cal, udate, &status);
	    int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    return val;
	} else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) {
	    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	    ucal_setMillis(calendar->_cal, udate, &status);
	    int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_MONTH, &status);
	    return val;
	}
	UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit);
	// Set calendar to first instant of big unit
	__CFCalendarSetToFirstInstant(calendar, biggerUnit, at);
	UDate curr = ucal_getMillis(calendar->_cal, &status);
        UDate goal = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	result = 1;
	const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14};
	int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]);
	Boolean divide = false, alwaysDivide = false;
	while (curr < goal) {
	    ucal_add(calendar->_cal, smallField, multiple, &status);
	    UDate newcurr = ucal_getMillis(calendar->_cal, &status);
	    if (curr < newcurr && newcurr <= goal) {
		result += multiple;
		curr = newcurr;
	    } else {
		// Either newcurr is going backwards, or not making
		// progress, or has overshot the goal; reset date
		// and try smaller multiples.
		ucal_setMillis(calendar->_cal, curr, &status);
		divide = true;
		// once we start overshooting the goal, the add at
		// smaller multiples will succeed at most once for
		// each multiple, so we reduce it every time through
		// the loop.
		if (goal < newcurr) alwaysDivide = true;
	    }
	    if (divide) {
		multiple = multiple / 2;
		if (0 == multiple) break;
		divide = alwaysDivide;
	    }
	}
    }
    return result;
}
Ejemplo n.º 3
0
VALUE icu4r_cal_cmp (VALUE c1, VALUE c2) 
{
	UErrorCode status = U_ZERO_ERROR;
	double  millis1, millis2;
	Check_Class(c1, rb_cUCalendar);
	Check_Class(c2, rb_cUCalendar);
	millis1 = ucal_getMillis(UCALENDAR(c1), &status); 
	millis2 = ucal_getMillis(UCALENDAR(c2), &status); 
	ICU_RAISE(status);
	if(millis1 < millis2) return INT2FIX(-1);
	if(millis1 > millis2) return INT2FIX(1);
	return INT2FIX(0);
}
Ejemplo n.º 4
0
Boolean _CFCalendarAddComponentsV(CFCalendarRef calendar, /* inout */ CFAbsoluteTime *atp, CFOptionFlags options, const char *componentDesc, int *vector, int count) {
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	UDate udate = floor((*atp + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	ucal_setMillis(calendar->_cal, udate, &status);
	char ch = *componentDesc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
            int amount = *vector;
	    if (options & kCFCalendarComponentsWrap) {
		ucal_roll(calendar->_cal, field, amount, &status);
	    } else {
		ucal_add(calendar->_cal, field, amount, &status);
	    }
	    vector++;
	    componentDesc++;
	    ch = *componentDesc;
	}
	udate = ucal_getMillis(calendar->_cal, &status);
	*atp = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970;
	return U_SUCCESS(status) ? true : false;
    }
    return false;
}
Ejemplo n.º 5
0
/**
 * call-seq:
 *     calendar.millis
 *
 * return this calendar value in milliseconds.
 */
VALUE icu4r_cal_millis(VALUE obj)
{
	UErrorCode status = U_ZERO_ERROR;
	double  millis;
	millis = ucal_getMillis(UCALENDAR(obj), &status); 
	ICU_RAISE(status);
	return rb_float_new(millis);
}
Ejemplo n.º 6
0
/** call-seq:
 *     calendar.format(pattern = nil , locale = nil)
 *
 * Formats this calendar time using given pattern and locale. Returns UString or nil on failure.
 * Valid value types for pattern are:
 *      nil        - long format for date and time
 *      UString    - specification of format, as defined in docs/FORMATTING
 *      Symbol     - one of :short, :medium, :long, :full, :none , sets format for both date and time
 *      Hash       - {:time => aSymbol, :date => aSymbol} - sets separate formats for date and time, valid symbols see above
 */
VALUE icu4r_cal_format(int argc, VALUE * argv, VALUE obj) 
{
	UErrorCode status = U_ZERO_ERROR;
	UDateFormat * format;
	UDate   time_to_format;
	UChar * buf = NULL, * pattern = NULL;
	long capa = 0, pattern_len = 0;
	char *locale = NULL;
	VALUE loc, pat, ret = Qnil;
	int n , def_d_format = UDAT_FULL, def_t_format = UDAT_FULL;
	
	n = rb_scan_args(argc, argv, "02", &pat, &loc);
	if( n == 2) {
		Check_Type(loc, T_STRING);
		locale = RSTRING_PTR(loc);
	}
	if (n >= 1 && pat != Qnil) {
		switch(TYPE(pat)) {
			case T_SYMBOL:
			 	def_d_format = def_t_format = icu4r_get_cal_format_int(pat);
				break;
			case T_HASH:
			 	def_d_format = icu4r_get_cal_format_int(rb_hash_aref(pat, ID2SYM(rb_intern("date"))));
				def_t_format = icu4r_get_cal_format_int(rb_hash_aref(pat, ID2SYM(rb_intern("time"))));
				break;
			default:
				Check_Class(pat, rb_cUString);
				pattern = ICU_PTR(pat);
				pattern_len = ICU_LEN(pat);
				break;
		}
	}
	
	format = udat_open(def_t_format, def_d_format, locale, NULL, 0,  NULL, 0, &status);
	if( pattern ) {
	   udat_applyPattern(format, 0, pattern, pattern_len);
	}
	ICU_RAISE(status);
	udat_setCalendar(format, UCALENDAR(obj));
	time_to_format = ucal_getMillis(UCALENDAR(obj), &status); 

	capa = udat_format(format, time_to_format, buf, capa, NULL, &status);
	if( U_BUFFER_OVERFLOW_ERROR == status) {
		buf = ALLOC_N(UChar, capa+1);
		status = U_ZERO_ERROR;
		capa = udat_format(format, time_to_format, buf, capa, NULL, &status);
		ret = icu_ustr_new_set(buf, capa, capa+1);
	}
	udat_close(format);
	ICU_RAISE(status);
	return ret;
}
Ejemplo n.º 7
0
void TestQuotePattern161()
{
    UDateFormat *format;
    UCalendar *cal;
    UDate currentTime_1;
    UChar *pattern, *tzID, *exp;
    UChar *dateString;
    UErrorCode status = U_ZERO_ERROR;
    const char* expStr = "04/13/1999 at 10:42:28 AM ";

    ctest_setTimeZone(NULL, &status);

    pattern=(UChar*)malloc(sizeof(UChar) * (strlen("MM/dd/yyyy 'at' hh:mm:ss a zzz")+1) );
    u_uastrcpy(pattern, "MM/dd/yyyy 'at' hh:mm:ss a zzz");
    
    /* this is supposed to open default date format, but later on it treats it like it is "en_US" 
       - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
    /* format= udat_openPattern(pattern, u_strlen(pattern), NULL, &status); */
    format= udat_open(UDAT_IGNORE, UDAT_IGNORE,"en_US", NULL, 0,pattern, u_strlen(pattern), &status);
    if(U_FAILURE(status)){
        log_err_status(status, "error in udat_open: %s\n", myErrorName(status));
        return;
    }
    tzID=(UChar*)malloc(sizeof(UChar) * 4);
    u_uastrcpy(tzID, "PST");
    /* this is supposed to open default date format, but later on it treats it like it is "en_US" 
       - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
    /* cal=ucal_open(tzID, u_strlen(tzID), NULL, UCAL_TRADITIONAL, &status); */
    cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    if(U_FAILURE(status)){ log_err("error in ucal_open cal : %s\n", myErrorName(status));    }
    
    ucal_setDateTime(cal, 1999, UCAL_APRIL, 13, 10, 42, 28, &status);
    currentTime_1 = ucal_getMillis(cal, &status);
    
    dateString = myDateFormat(format, currentTime_1);
    exp=(UChar*)malloc(sizeof(UChar) * (strlen(expStr) + 1) );
    u_uastrcpy(exp, expStr);
    
    log_verbose("%s\n", austrdup(dateString) );
    if(u_strncmp(dateString, exp, (int32_t)strlen(expStr)) !=0)
        log_err("Error in formatting a pattern with single quotes\n");

    udat_close(format);
    ucal_close(cal);
    free(exp);
    free(tzID);
    free(pattern);
    
    ctest_resetTimeZone();
}
Ejemplo n.º 8
0
Boolean _CFCalendarGetComponentDifferenceV(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, int **vector, int count) {
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	UDate curr = floor((startingAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	UDate goal = floor((resultAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	ucal_setMillis(calendar->_cal, curr, &status);
	int direction = (startingAT <= resultAT) ? 1 : -1;
	char ch = *componentDesc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
	    const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14};
	    int multiple = direction * (1 << multiple_table[flsl(__CFCalendarGetCalendarUnitFromChar(ch)) - 1]);
	    Boolean divide = false, alwaysDivide = false;
	    int result = 0;
	    while ((direction > 0 && curr < goal) || (direction < 0 && goal < curr)) {
		ucal_add(calendar->_cal, field, multiple, &status);
		UDate newcurr = ucal_getMillis(calendar->_cal, &status);
		if ((direction > 0 && curr < newcurr && newcurr <= goal) || (direction < 0 && newcurr < curr && goal <= newcurr)) {
		    result += multiple;
		    curr = newcurr;
		} else {
		    // Either newcurr is going backwards, or not making
		    // progress, or has overshot the goal; reset date
		    // and try smaller multiples.
		    ucal_setMillis(calendar->_cal, curr, &status);
		    divide = true;
		    // once we start overshooting the goal, the add at
		    // smaller multiples will succeed at most once for
		    // each multiple, so we reduce it every time through
		    // the loop.
		    if ((direction > 0 && goal < newcurr) || (direction < 0 && newcurr < goal)) alwaysDivide = true;
		}
		if (divide) {
		    multiple = multiple / 2;
		    if (0 == multiple) break;
		    divide = alwaysDivide;
		}
	    }
	    *(*vector) = result;
	    vector++;
	    componentDesc++;
	    ch = *componentDesc;
	}
	return U_SUCCESS(status) ? true : false;
    }
    return false;
}
Ejemplo n.º 9
0
/* {{{
 * Internal function which sets UCalendar  from the passed array and retrieves timestamp
*/
static UDate internal_get_timestamp(IntlDateFormatter_object *dfo,
		HashTable *hash_arr)
{
	int32_t		year,
				month,
				hour,
				minute,
				second,
				mday;
	UCalendar	*pcal;
	UDate		result;
	intl_error	*err = &dfo->datef_data.error;

#define INTL_GET_ELEM(elem) \
	internal_get_arr_ele(dfo, hash_arr, (elem), err)

	/* Fetch  values from the incoming array */
	year	= INTL_GET_ELEM(CALENDAR_YEAR) + 1900; /* tm_year is years since 1900 */
	/* Month in ICU and PHP starts from January =0 */
	month	= INTL_GET_ELEM(CALENDAR_MON);
	hour	= INTL_GET_ELEM(CALENDAR_HOUR);
	minute	= INTL_GET_ELEM(CALENDAR_MIN);
	second	= INTL_GET_ELEM(CALENDAR_SEC);
	/* For the ucal_setDateTime() function, this is the 'date'  value */
	mday	= INTL_GET_ELEM(CALENDAR_MDAY);

#undef INTL_GET_ELEM

	pcal = ucal_clone(udat_getCalendar(DATE_FORMAT_OBJECT(dfo)),
			&INTL_DATA_ERROR_CODE(dfo));

	if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) {
		intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "datefmt_format: "
				"error cloning calendar", 0);
		return 0;
	}

	/* set the incoming values for the calendar */
	ucal_setDateTime(pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo));
	/* actually, ucal_setDateTime cannot fail */

	/* Fetch the timestamp from the UCalendar */
	result = ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo));
	ucal_close(pcal);
	return result;
}
Ejemplo n.º 10
0
/*
 * ICU's Universal Time Scale is designed to be tick-for-tick compatible with
 * .Net System.DateTime. Verify that this is so for the
 * .Net-supported date range (years 1-9999 AD).
 * This requires a proleptic Gregorian calendar because that's what .Net uses.
 * Proleptic: No Julian/Gregorian switchover, or a switchover before
 * any date that we test, that is, before 0001 AD.
 */
static void
TestDotNet() {
    static const UChar utc[] = { 0x45, 0x74, 0x63, 0x2f, 0x47, 0x4d, 0x54, 0 }; /* "Etc/GMT" */
    const int32_t dayMillis = 86400 * INT64_C(1000);    /* 1 day = 86400 seconds */
    const int64_t dayTicks = 86400 * INT64_C(10000000);
    const DotNetDateTimeTicks *dt;
    UCalendar *cal;
    UErrorCode errorCode;
    UDate icuDate;
    int64_t ticks, millis;
    int32_t i;

    /* Open a proleptic Gregorian calendar. */
    errorCode = U_ZERO_ERROR;
    cal = ucal_open(utc, -1, "", UCAL_GREGORIAN, &errorCode);
    ucal_setGregorianChange(cal, -1000000 * (dayMillis * (UDate)1), &errorCode);
    if(U_FAILURE(errorCode)) {
        log_err("ucal_open(UTC/proleptic Gregorian) failed: %s\n", u_errorName(errorCode));
        ucal_close(cal);
        return;
    }
    for(i = 0; i < LENGTHOF(dotNetDateTimeTicks); ++i) {
        /* Test conversion from .Net/Universal time to ICU time. */
        dt = dotNetDateTimeTicks + i;
        millis = utmscale_toInt64(dt->ticks, UDTS_ICU4C_TIME, &errorCode);
        ucal_clear(cal);
        ucal_setDate(cal, dt->year, dt->month - 1, dt->day, &errorCode); /* Java & ICU use January = month 0. */
        icuDate = ucal_getMillis(cal, &errorCode);
        if(millis != icuDate) {
            /* Print days not millis to stay within printf() range. */
            log_err("utmscale_toInt64(ticks[%d], ICU4C)=%dd != %dd=ucal_getMillis(%04d-%02d-%02d)\n",
                    (int)i, (int)(millis/dayMillis), (int)(icuDate/dayMillis), (int)dt->year, (int)dt->month, (int)dt->day);
        }

        /* Test conversion from ICU time to .Net/Universal time. */
        ticks = utmscale_fromInt64((int64_t)icuDate, UDTS_ICU4C_TIME, &errorCode);
        if(ticks != dt->ticks) {
            /* Print days not ticks to stay within printf() range. */
            log_err("utmscale_fromInt64(date[%d], ICU4C)=%dd != %dd=.Net System.DateTime(%04d-%02d-%02d).Ticks\n",
                    (int)i, (int)(ticks/dayTicks), (int)(dt->ticks/dayTicks), (int)dt->year, (int)dt->month, (int)dt->day);
        }
    }

    ucal_close(cal);
}
Ejemplo n.º 11
0
Boolean _CFCalendarComposeAbsoluteTimeV(CFCalendarRef calendar, /* out */ CFAbsoluteTime *atp, const char *componentDesc, int *vector, int count) {
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	UErrorCode status = U_ZERO_ERROR;
	ucal_clear(calendar->_cal);
	ucal_set(calendar->_cal, UCAL_YEAR, 1);
	ucal_set(calendar->_cal, UCAL_MONTH, 0);
	ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, 1);
	ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, 0);
	ucal_set(calendar->_cal, UCAL_MINUTE, 0);
	ucal_set(calendar->_cal, UCAL_SECOND, 0);
	const char *desc = componentDesc;
	Boolean doWOY = false;
	char ch = *desc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
	    if (UCAL_WEEK_OF_YEAR == field) {
		doWOY = true;
	    }
	    desc++;
	    ch = *desc;
	}
	desc = componentDesc;
	ch = *desc;
	while (ch) {
	    UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch);
	    int value = *vector;
	    if (UCAL_YEAR == field && doWOY) field = UCAL_YEAR_WOY;
	    if (UCAL_MONTH == field) value--;
	    ucal_set(calendar->_cal, field, value);
	    vector++;
	    desc++;
	    ch = *desc;
	}
	UDate udate = ucal_getMillis(calendar->_cal, &status);
	CFAbsoluteTime at = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970;
        if (atp) *atp = at;
	return U_SUCCESS(status) ? true : false;
    }
    return false;
}
Ejemplo n.º 12
0
void TestCzechMonths459()
{
    int32_t lneed, pos;
    UChar *pattern=NULL, *tzID=NULL;
    UChar *juneStr, *julyStr;
    UDateFormat *fmt;
    UCalendar *cal;
    UDate june, july, d;
    UErrorCode status = U_ZERO_ERROR;
    UChar *date;
    
    ctest_setTimeZone(NULL, &status);
    fmt = udat_open(UDAT_FULL, UDAT_FULL, "cs", NULL, 0, NULL, 0, &status);
    if(U_FAILURE(status)){
        log_data_err("Error in constructing the date format -> %s (Are you missing data?)\n", u_errorName(status));
        ctest_resetTimeZone();
        return;
    }
    lneed=0;
    lneed=udat_toPattern(fmt, TRUE, NULL, lneed, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR){
        status=U_ZERO_ERROR;
        pattern=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
        udat_toPattern(fmt, TRUE, pattern, lneed+1, &status);
    }
    if(U_FAILURE(status)){ log_err("Error in extracting the pattern\n"); }
    tzID=(UChar*)malloc(sizeof(UChar) * 4);
    u_uastrcpy(tzID, "GMT");
    cal=ucal_open(tzID, u_strlen(tzID), "cs", UCAL_GREGORIAN, &status);
    if(U_FAILURE(status)){ log_err("error in ucal_open caldef : %s\n", myErrorName(status));    }
    
    ucal_setDate(cal, 1997, UCAL_JUNE, 15, &status);
    june=ucal_getMillis(cal, &status);
    ucal_setDate(cal, 1997, UCAL_JULY, 15, &status);
    july=ucal_getMillis(cal, &status);

    juneStr = myDateFormat(fmt, june);
    julyStr = myDateFormat(fmt, july);
    pos=0;
    if(juneStr == NULL) {
      log_data_err("Can't load juneStr. Quitting.\n");
      return;
    }
    d = udat_parse(fmt, juneStr, u_strlen(juneStr), &pos, &status);
    date = myDateFormat(fmt, d);

    if(U_SUCCESS(status)){
        UChar* out1 = myDateFormat(fmt, june);
        UChar* out2 = myDateFormat(fmt, d);
        if(u_strcmp(out1, out2) !=0)
            log_err("Error in handling the czech month june\n");
        else
            log_verbose("Pass: Date = %s (czech month June)\n", aescstrdup(date, -1));
    }else{
        log_err("udat_parse failed. Error. %s\n",u_errorName(status));
    }
    pos=0;
    d = udat_parse(fmt, julyStr, u_strlen(julyStr), &pos, &status);
    date = myDateFormat(fmt, d);
    if(u_strcmp(myDateFormat(fmt, july), myDateFormat(fmt, d) ) !=0)
        log_err("Error in handling the czech month july\n");
    else
        log_verbose("Pass: Date = %s (czech month July)\n", aescstrdup(date, -1));
    
    ctest_resetTimeZone();
    udat_close(fmt);
    ucal_close(cal);
    free(pattern);
    free(tzID);
}
Ejemplo n.º 13
0
static CFRange __CFCalendarGetRangeOfUnit1(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
    CFRange range = {kCFNotFound, kCFNotFound};
    if (!__validUnits(smallerUnit, biggerUnit)) return range;
    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFRange, calendar, "_rangeOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
    __CFGenericValidateType(calendar, CFCalendarGetTypeID());
    if (!calendar->_cal) __CFCalendarSetupCal(calendar);
    if (calendar->_cal) {
	int32_t dow = -1;
	ucal_clear(calendar->_cal);
	UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit);
	UCalendarDateFields bigField = __CFCalendarGetICUFieldCode(biggerUnit);
	if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) {
	    UErrorCode status = U_ZERO_ERROR;
	    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
	    ucal_setMillis(calendar->_cal, udate, &status);
	    dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
	}
	// Set calendar to first instant of big unit
	__CFCalendarSetToFirstInstant(calendar, biggerUnit, at);
	UErrorCode status = U_ZERO_ERROR;
	UDate start = ucal_getMillis(calendar->_cal, &status);
	if (kCFCalendarUnitWeek == biggerUnit) {
	    range.location = ucal_get(calendar->_cal, smallField, &status);
	    if (kCFCalendarUnitMonth == smallerUnit) range.location++;
	} else {
	    range.location = (kCFCalendarUnitHour == smallerUnit || kCFCalendarUnitMinute == smallerUnit || kCFCalendarUnitSecond == smallerUnit) ? 0 : 1;
	}
	// Set calendar to first instant of next value of big unit
	if (UCAL_ERA == bigField) {
	    // ICU refuses to do the addition, probably because we are
	    // at the limit of UCAL_ERA.  Use alternate strategy.
	    CFIndex limit = ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_MAXIMUM, &status);
	    if (100000 < limit) limit = 100000;
	    ucal_add(calendar->_cal, UCAL_YEAR, limit, &status);
	} else {
	    ucal_add(calendar->_cal, bigField, 1, &status);
	}
	if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) {
	    ucal_add(calendar->_cal, UCAL_SECOND, -1, &status);
	    range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    while (1 == range.length) {
		ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, -1, &status);
		range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    }
	    range.location = 1;
	    return range;
	} else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) {
	    ucal_add(calendar->_cal, UCAL_SECOND, -1, &status);
	    range.length = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status);
	    range.location = 1;
	    return range;
	}
	UDate goal = ucal_getMillis(calendar->_cal, &status);
	// Set calendar back to first instant of big unit
	ucal_setMillis(calendar->_cal, start, &status);
	if (kCFCalendarUnitWeekdayOrdinal == smallerUnit) {
	    // roll day forward to first 'dow'
	    while (ucal_get(calendar->_cal, (kCFCalendarUnitMonth == biggerUnit) ? UCAL_WEEK_OF_MONTH : UCAL_WEEK_OF_YEAR, &status) != 1) {
		ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status);
	    }
	    while (ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != dow) {
		ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status);
	    }
	    start = ucal_getMillis(calendar->_cal, &status);
	    goal -= 1000;
	    range.location = 1;  // constant here works around ICU -- see 3948293
	}
	UDate curr = start;
	range.length = 	(kCFCalendarUnitWeekdayOrdinal == smallerUnit) ? 1 : 0;
	const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14};
	int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]);
	Boolean divide = false, alwaysDivide = false;
	while (curr < goal) {
	    ucal_add(calendar->_cal, smallField, multiple, &status);
	    UDate newcurr = ucal_getMillis(calendar->_cal, &status);
	    if (curr < newcurr && newcurr <= goal) {
		range.length += multiple;
		curr = newcurr;
	    } else {
		// Either newcurr is going backwards, or not making
		// progress, or has overshot the goal; reset date
		// and try smaller multiples.
		ucal_setMillis(calendar->_cal, curr, &status);
		divide = true;
		// once we start overshooting the goal, the add at
		// smaller multiples will succeed at most once for
		// each multiple, so we reduce it every time through
		// the loop.
		if (goal < newcurr) alwaysDivide = true;
	    }
	    if (divide) {
		multiple = multiple / 2;
		if (0 == multiple) break;
		divide = alwaysDivide;
	    }
	}
    }
    return range;
}
Ejemplo n.º 14
0
static void __CFCalendarSetToFirstInstant(CFCalendarRef calendar, CFCalendarUnit unit, CFAbsoluteTime at) {
    // Set UCalendar to first instant of unit prior to 'at'
    UErrorCode status = U_ZERO_ERROR;
    UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0);
    ucal_setMillis(calendar->_cal, udate, &status);
    int target_era = INT_MIN;
    switch (unit) { // largest to smallest, we set the fields to their minimum value
    case kCFCalendarUnitWeek:
	{
	// reduce to first day of week, then reduce the rest of the day
        int32_t goal = ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK);
	int32_t dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
	while (dow != goal) {
	    ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, -1, &status);
	    dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status);
	}
	goto day;
	}
    case kCFCalendarUnitEra:
	{
	target_era = ucal_get(calendar->_cal, UCAL_ERA, &status);
	ucal_set(calendar->_cal, UCAL_YEAR, ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_ACTUAL_MINIMUM, &status));
	}
    case kCFCalendarUnitYear:
	ucal_set(calendar->_cal, UCAL_MONTH, ucal_getLimit(calendar->_cal, UCAL_MONTH, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitMonth:
	ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, ucal_getLimit(calendar->_cal, UCAL_DAY_OF_MONTH, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitWeekday:
    case kCFCalendarUnitDay:
    day:;
	ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, ucal_getLimit(calendar->_cal, UCAL_HOUR_OF_DAY, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitHour:
	ucal_set(calendar->_cal, UCAL_MINUTE, ucal_getLimit(calendar->_cal, UCAL_MINUTE, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitMinute:
	ucal_set(calendar->_cal, UCAL_SECOND, ucal_getLimit(calendar->_cal, UCAL_SECOND, UCAL_ACTUAL_MINIMUM, &status));
    case kCFCalendarUnitSecond:
	ucal_set(calendar->_cal, UCAL_MILLISECOND, 0);
    }
    if (INT_MIN != target_era && ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) {
	// In the Japanese calendar, and possibly others, eras don't necessarily
	// start on the first day of a year, so the previous code may have backed
	// up into the previous era, and we have to correct forward.
	UDate bad_udate = ucal_getMillis(calendar->_cal, &status);
	ucal_add(calendar->_cal, UCAL_MONTH, 1, &status);
	while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) {
	    bad_udate = ucal_getMillis(calendar->_cal, &status);
	    ucal_add(calendar->_cal, UCAL_MONTH, 1, &status);
	}
	udate = ucal_getMillis(calendar->_cal, &status);
	// target date is between bad_udate and udate
	for (;;) {
	    UDate test_udate = (udate + bad_udate) / 2;
	    ucal_setMillis(calendar->_cal, test_udate, &status);
	    if (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) {
		bad_udate = test_udate;
	    } else {
		udate = test_udate;
	    }
	    if (fabs(udate - bad_udate) < 1000) break;
	}
	do {
	    bad_udate = floor((bad_udate + 1000) / 1000) * 1000;
	    ucal_setMillis(calendar->_cal, bad_udate, &status);
	} while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era);
    }
}
Ejemplo n.º 15
0
/* Print out a calendar for c's current year */
static void
print_year(UCalendar *c,
           UChar *days [],
           UChar *months [],
           UBool useLongNames,
           int32_t fdow,
           UErrorCode *status)
{
    int32_t width, pad, i, j;
    int32_t lens [DAY_COUNT];
    UNumberFormat *nfmt;
    UDateFormat *dfmt;
    UChar s [BUF_SIZE];
    const UChar pat [] = { 0x0079, 0x0079, 0x0079, 0x0079 };
    int32_t len = 4;
    UCalendar  *left_cal, *right_cal;
    int32_t left_day, right_day;
    int32_t left_firstday, right_firstday, left_current, right_current;
    int32_t left_month, right_month;

    if(U_FAILURE(*status)) return;

    /* Alias */
    left_cal = c;

    /* ========== Generate the header containing the year (only) */

    /* Open a formatter with a month and year only pattern */
    dfmt = udat_open(UDAT_IGNORE,UDAT_IGNORE,NULL,NULL,0,pat, len, status);

    /* Format the date */
    udat_format(dfmt, ucal_getMillis(left_cal, status), s, BUF_SIZE, 0, status);

    /* ========== Get the month and day names */
    get_days(dfmt, days, useLongNames, fdow, status);
    get_months(dfmt, months, useLongNames, status);

    /* ========== Print the header, centered */

    /* Calculate widths for justification */
    width = 6; /* 6 spaces, 1 between each day name */
    for(i = 0; i < DAY_COUNT; ++i) {
        lens[i] = u_strlen(days[i]);
        width += lens[i];
    }

    /* width is the width for 1 calendar; we are displaying in 2 cols
    with MARGIN_WIDTH spaces between months */

    /* Print the header, centered among the day names */
    pad = 2 * width + MARGIN_WIDTH - u_strlen(s);
    indent(pad / 2, stdout);
    uprint(s, stdout, status);
    putc('\n', stdout);
    putc('\n', stdout);

    /* Generate a copy of the calendar to use */
    right_cal = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status);
    ucal_setMillis(right_cal, ucal_getMillis(left_cal, status), status);

    /* Open the formatter */
    nfmt = unum_open(UNUM_DECIMAL,NULL, 0,NULL,NULL, status);

    /* ========== Calculate and display the months, two at a time */
    for(i = 0; i < MONTH_COUNT - 1; i += 2) {

        /* Print the month names for the two current months */
        pad = width - u_strlen(months[i]);
        indent(pad / 2, stdout);
        uprint(months[i], stdout, status);
        indent(pad / 2 + MARGIN_WIDTH, stdout);
        pad = width - u_strlen(months[i + 1]);
        indent(pad / 2, stdout);
        uprint(months[i + 1], stdout, status);
        putc('\n', stdout);

        /* Print the day names, twice  */
        print_days(days, stdout, status);
        indent(MARGIN_WIDTH, stdout);
        print_days(days, stdout, status);
        putc('\n', stdout);

        /* Setup the two calendars */
        ucal_set(left_cal, UCAL_MONTH, i);
        ucal_set(left_cal, UCAL_DATE, 1);
        ucal_set(right_cal, UCAL_MONTH, i + 1);
        ucal_set(right_cal, UCAL_DATE, 1);

        left_firstday = ucal_get(left_cal, UCAL_DAY_OF_WEEK, status);
        right_firstday = ucal_get(right_cal, UCAL_DAY_OF_WEEK, status);

        /* The day of the week for the first day of the month is based on
        1-based days of the week.  However, the days were reordered
        when placed in the days array.  Account for this here by
        offsetting by the first day of the week for the locale, which
        is also 1-based. */

        /* We need to mod by DAY_COUNT since fdow can be > firstday.  IE,
        if fdow = 2 = Monday (like in France) and the first day of the
        month is a 1 = Sunday, we want firstday to be 6, not -1 */
        left_firstday += (DAY_COUNT - fdow);
        left_firstday %= DAY_COUNT;

        right_firstday += (DAY_COUNT - fdow);
        right_firstday %= DAY_COUNT;

        left_current = left_firstday;
        right_current = right_firstday;

        left_day = ucal_get(left_cal, UCAL_DATE, status);
        right_day = ucal_get(right_cal, UCAL_DATE, status);

        left_month = ucal_get(left_cal, UCAL_MONTH, status);
        right_month = ucal_get(right_cal, UCAL_MONTH, status);

        /* Finally, print out the days */
        while(left_month == i || right_month == i + 1) {

            /* If the left month is finished printing, but the right month
            still has days to be printed, indent the width of the days
                strings and reset the left calendar's current day to 0 */
            if(left_month != i && right_month == i + 1) {
                indent(width + 1, stdout);
                left_current = 0;
            }

            while(left_month == i) {

                /* If the day is the first, indent the correct number of
                    spaces for the first week */
                if(left_day == 1) {
                    for(j = 0; j < left_current; ++j)
                        indent(lens[j] + 1, stdout);
                }

                /* Format the current day string */
                unum_format(nfmt, left_day, s, BUF_SIZE, 0, status);

                /* Calculate the justification and indent */
                pad = lens[left_current] - u_strlen(s);
                indent(pad, stdout);

                /* Print the day number out, followed by a space */
                uprint(s, stdout, status);
                putc(' ', stdout);

                /* Update the current day */
                ++left_current;
                left_current %= DAY_COUNT;

                /* Go to the next day */
                ucal_add(left_cal, UCAL_DATE, 1, status);
                left_day = ucal_get(left_cal, UCAL_DATE, status);

                /* Determine the month */
                left_month = ucal_get(left_cal, UCAL_MONTH, status);

                /* If we're at day 0 (first day of the week), break and go to
                the next month */
                if(left_current == 0) {
                    break;
                }
            };

            /* If the current day isn't 0, indent to make up for missing
            days at the end of the month */
            if(left_current != 0) {
                for(j = left_current; j < DAY_COUNT; ++j)
                    indent(lens[j] + 1, stdout);
            }

            /* Indent between the two months */
            indent(MARGIN_WIDTH, stdout);

            while(right_month == i + 1) {

                /* If the day is the first, indent the correct number of
                    spaces for the first week */
                if(right_day == 1) {
                    for(j = 0; j < right_current; ++j)
                        indent(lens[j] + 1, stdout);
                }

                /* Format the current day string */
                unum_format(nfmt, right_day, s, BUF_SIZE, 0, status);

                /* Calculate the justification and indent */
                pad = lens[right_current] - u_strlen(s);
                indent(pad, stdout);

                /* Print the day number out, followed by a space */
                uprint(s, stdout, status);
                putc(' ', stdout);

                /* Update the current day */
                ++right_current;
                right_current %= DAY_COUNT;

                /* Go to the next day */
                ucal_add(right_cal, UCAL_DATE, 1, status);
                right_day = ucal_get(right_cal, UCAL_DATE, status);

                /* Determine the month */
                right_month = ucal_get(right_cal, UCAL_MONTH, status);

                /* If we're at day 0 (first day of the week), break out */
                if(right_current == 0) {
                    break;
                }

            };

            /* Output a newline */
            putc('\n', stdout);
        }

        /* Output a trailing newline */
        putc('\n', stdout);
    }

    /* Clean up */
    free_months(months);
    free_days(days);
    udat_close(dfmt);
    unum_close(nfmt);
    ucal_close(right_cal);
}
Ejemplo n.º 16
0
static void TestRelativeDateFormat()
{
    UDate today = 0.0;
    const UDateFormatStyle * stylePtr;
    const UChar ** monthPtnPtr;
    UErrorCode status = U_ZERO_ERROR;
    UCalendar * ucal = ucal_open(trdfZone, -1, trdfLocale, UCAL_GREGORIAN, &status);
    if ( U_SUCCESS(status) ) {
        int32_t    year, month, day;
        ucal_setMillis(ucal, ucal_getNow(), &status);
        year = ucal_get(ucal, UCAL_YEAR, &status);
        month = ucal_get(ucal, UCAL_MONTH, &status);
        day = ucal_get(ucal, UCAL_DATE, &status);
        ucal_setDateTime(ucal, year, month, day, 18, 49, 0, &status); /* set to today at 18:49:00 */
        today = ucal_getMillis(ucal, &status);
        ucal_close(ucal);
    }
    if ( U_FAILURE(status) || today == 0.0 ) {
        log_data_err("Generate UDate for a specified time today fails, error %s - (Are you missing data?)\n", myErrorName(status) );
        return;
    }
    for (stylePtr = dateStylesList, monthPtnPtr = monthPatnsList; *stylePtr != UDAT_NONE; ++stylePtr, ++monthPtnPtr) {
        UDateFormat* fmtRelDateTime;
        UDateFormat* fmtRelDate;
        UDateFormat* fmtTime;
        int32_t dayOffset, limit;
        UFieldPosition fp;
		UChar   strDateTime[kDateAndTimeOutMax];
		UChar   strDate[kDateOrTimeOutMax];
		UChar   strTime[kDateOrTimeOutMax];
		UChar * strPtr;
        int32_t dtpatLen;

        fmtRelDateTime = udat_open(UDAT_SHORT, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
        if ( U_FAILURE(status) ) {
            log_data_err("udat_open timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s (Are you missing data?)\n", *stylePtr, myErrorName(status) );
            continue;
        }
        fmtRelDate = udat_open(UDAT_NONE, *stylePtr | UDAT_RELATIVE, trdfLocale, trdfZone, -1, NULL, 0, &status);
        if ( U_FAILURE(status) ) {
            log_err("udat_open timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
            udat_close(fmtRelDateTime);
            continue;
        }
        fmtTime = udat_open(UDAT_SHORT, UDAT_NONE, trdfLocale, trdfZone, -1, NULL, 0, &status);
        if ( U_FAILURE(status) ) {
            log_err("udat_open timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
            udat_close(fmtRelDateTime);
            udat_close(fmtRelDate);
            continue;
        }

        dtpatLen = udat_toPatternRelativeDate(fmtRelDateTime, strDate, kDateAndTimeOutMax, &status);
        if ( U_FAILURE(status) ) {
        	log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
        	status = U_ZERO_ERROR;
        } else if ( u_strstr(strDate, *monthPtnPtr) == NULL || dtpatLen != u_strlen(strDate) ) {
        	log_err("udat_toPatternRelativeDate timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) date pattern incorrect\n", *stylePtr );
        }
        dtpatLen = udat_toPatternRelativeTime(fmtRelDateTime, strTime, kDateAndTimeOutMax, &status);
        if ( U_FAILURE(status) ) {
        	log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
        	status = U_ZERO_ERROR;
        } else if ( u_strstr(strTime, minutesPatn) == NULL || dtpatLen != u_strlen(strTime) ) {
        	log_err("udat_toPatternRelativeTime timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) time pattern incorrect\n", *stylePtr );
        }
        dtpatLen = udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
        if ( U_FAILURE(status) ) {
        	log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
        	status = U_ZERO_ERROR;
        } else if ( u_strstr(strDateTime, strDate) == NULL || u_strstr(strDateTime, strTime) == NULL || dtpatLen != u_strlen(strDateTime) ) {
        	log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) dateTime pattern incorrect\n", *stylePtr );
        }
        udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), newTimePatn, u_strlen(newTimePatn), &status);
        if ( U_FAILURE(status) ) {
        	log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
        	status = U_ZERO_ERROR;
        } else {
        	udat_toPattern(fmtRelDateTime, FALSE, strDateTime, kDateAndTimeOutMax, &status);
        	if ( U_FAILURE(status) ) {
        		log_err("udat_toPattern timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
        		status = U_ZERO_ERROR;
        	} else if ( u_strstr(strDateTime, newTimePatn) == NULL ) {
        		log_err("udat_applyPatternRelative timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) didn't update time pattern\n", *stylePtr );
        	}
        }
        udat_applyPatternRelative(fmtRelDateTime, strDate, u_strlen(strDate), strTime, u_strlen(strTime), &status); /* restore original */

        fp.field = UDAT_MINUTE_FIELD;
        for (dayOffset = -2, limit = 2; dayOffset <= limit; ++dayOffset) {
            UDate   dateToUse = today + (float)dayOffset*dayInterval;

            udat_format(fmtRelDateTime, dateToUse, strDateTime, kDateAndTimeOutMax, &fp, &status);
            if ( U_FAILURE(status) ) {
                log_err("udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
                status = U_ZERO_ERROR;
            } else {
                udat_format(fmtRelDate, dateToUse, strDate, kDateOrTimeOutMax, NULL, &status);
                if ( U_FAILURE(status) ) {
                    log_err("udat_format timeStyle NONE dateStyle (%d | UDAT_RELATIVE) fails, error %s\n", *stylePtr, myErrorName(status) );
                    status = U_ZERO_ERROR;
                } else if ( u_strstr(strDateTime, strDate) == NULL ) {
                    log_err("relative date string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
                }

                udat_format(fmtTime, dateToUse, strTime, kDateOrTimeOutMax, NULL, &status);
                if ( U_FAILURE(status) ) {
                    log_err("udat_format timeStyle SHORT dateStyle NONE fails, error %s\n", myErrorName(status) );
                    status = U_ZERO_ERROR;
                } else if ( u_strstr(strDateTime, strTime) == NULL ) {
                    log_err("time string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
                }

                strPtr = u_strstr(strDateTime, minutesStr);
                if ( strPtr != NULL ) {
                    int32_t beginIndex = strPtr - strDateTime;
                    if ( fp.beginIndex != beginIndex ) {
                        log_err("UFieldPosition beginIndex %d, expected %d, in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", fp.beginIndex, beginIndex, *stylePtr );
                    }
                } else {
                    log_err("minutes string not found in udat_format timeStyle SHORT dateStyle (%d | UDAT_RELATIVE)\n", *stylePtr );
                }
            }
        }

        udat_close(fmtRelDateTime);
        udat_close(fmtRelDate);
        udat_close(fmtTime);
     }
}
Ejemplo n.º 17
0
// This function from ICU 4.2
static int32_t 
dateFieldDifference(UCalendar* cal, 
    UDate targetMs, 
    UCalendarDateFields field, 
    UErrorCode& status) {
    UDate startMs, ms;

    if (U_FAILURE(status)) return 0;
    int32_t min = 0;

    startMs = ucal_getMillis(cal, &status);
    if (U_FAILURE(status)) return 0;

    // Always add from the start millis.  This accomodates
    // operations like adding years from February 29, 2000 up to
    // February 29, 2004.  If 1, 1, 1, 1 is added to the year
    // field, the DOM gets pinned to 28 and stays there, giving an
    // incorrect DOM difference of 1.  We have to add 1, reset, 2,
    // reset, 3, reset, 4.
    if (startMs < targetMs) {
        int32_t max = 1;
        // Find a value that is too large
        while (U_SUCCESS(status)) {
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, max, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return max;
            } else if (ms > targetMs) {
                break;
            } else {
                min = max;
                max <<= 1;
                if (max < 0) {
                    // Field difference too large to fit into int32_t
                    status = U_ILLEGAL_ARGUMENT_ERROR;
                }
            }
        }
        // Do a binary search
        while ((max - min) > 1 && U_SUCCESS(status)) {
            int32_t t = (min + max) / 2;
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, t, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return t;
            } else if (ms > targetMs) {
                max = t;
            } else {
                min = t;
            }
        }
    } else if (startMs > targetMs) {
        int32_t max = -1;
        // Find a value that is too small
        while (U_SUCCESS(status)) {
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, max, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return max;
            } else if (ms < targetMs) {
                break;
            } else {
                min = max;
                max <<= 1;
                if (max == 0) {
                    // Field difference too large to fit into int32_t
                    status = U_ILLEGAL_ARGUMENT_ERROR;
                }
            }
        }
        // Do a binary search
        while ((min - max) > 1 && U_SUCCESS(status)) {
            int32_t t = (min + max) / 2;
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, t, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return t;
            } else if (ms < targetMs) {
                max = t;
            } else {
                min = t;
            }
        }
    }
    // Set calendar to end point
    ucal_setMillis(cal, startMs, &status);
    ucal_add(cal, field, min, &status);

    /* Test for buffer overflows */
    if(U_FAILURE(status)) {
        return 0;
    }
    return min;
}
Ejemplo n.º 18
0
/* This function is from ICU 4.2. */
static int32_t 
dateFieldDifference(UCalendar* cal, 
    UDate targetMs, 
    UCalendarDateFields field, 
    UErrorCode& status) {
    UDate startMs, ms;

    if (U_FAILURE(status)) return 0;
    int32_t min = 0;

    startMs = ucal_getMillis(cal, &status);
    if (U_FAILURE(status)) return 0;

    /*
       Always add from the start millis.  This accomodates
       operations like adding years from February 29, 2000 up to
       February 29, 2004.  If 1, 1, 1, 1 is added to the year
       field, the DOM gets pinned to 28 and stays there, giving an
       incorrect DOM difference of 1.  We have to add 1, reset, 2,
       reset, 3, reset, 4.
    */
    if (startMs < targetMs) {
        int32_t max = 1;
        /* Find a value that is too large */
        while (U_SUCCESS(status)) {
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, max, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return max;
            } else if (ms > targetMs) {
                break;
            } else {
                min = max;
                max <<= 1;
                if (max < 0) {
                    /* Field difference too large to fit into int32_t */
                    status = U_UNSUPPORTED_ERROR;
                }
            }
        }

        /* Do a binary search */
        while ((max - min) > 1 && U_SUCCESS(status)) {
            int32_t t = (min + max) / 2;
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, t, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return t;
            } else if (ms > targetMs) {
                max = t;
            } else {
                min = t;
            }
        }

        /* It is an bad type for this algorithm. */
        if (ms < startMs)
            status = U_UNSUPPORTED_ERROR;

    } else if (startMs > targetMs) {
        int32_t max = -1;
        /* Find a value that is too small */
        while (U_SUCCESS(status)) {
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, max, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return max;
            } else if (ms < targetMs) {
                break;
            } else {
                min = max;
                max <<= 1;
                if (max == 0) {
                    /* Field difference too large to fit into int32_t */
                    status = U_UNSUPPORTED_ERROR;
                }
            }
        }

        /* Do a binary search */
        while ((min - max) > 1 && U_SUCCESS(status)) {
            int32_t t = (min + max) / 2;
            ucal_setMillis(cal, startMs, &status);
            ucal_add(cal, field, t, &status);
            ms = ucal_getMillis(cal, &status);

            if (ms == targetMs) {
                return t;
            } else if (ms < targetMs) {
                max = t;
            } else {
                min = t;
            }
        }

        /*
           It is an bad type for this algorithm.
           For example, 
           i18n_date:difference(i18n_date:new(-2000,1,1),
              i18n_date:new(2000,1,1),year).
        */

        if (U_SUCCESS(status) && (ms > startMs))
            status = U_UNSUPPORTED_ERROR;
    }
    /* Set calendar to end point */
    ucal_setMillis(cal, startMs, &status);
    ucal_add(cal, field, min, &status);

    /* Test for buffer overflows */
    if(U_FAILURE(status)) {
        return 0;
    }
    return min;
}
Ejemplo n.º 19
0
/* Test u_formatMessage() and u_parseMessage() , format and parse sequence and round trip */
static void TestSampleFormatAndParse(void)
{

    UChar *result, *tzID, *str;
    UChar pattern[100];
    UChar expected[100];
    int32_t resultLengthOut, resultlength;
    UCalendar *cal;
    UDate d1,d;
    UDateFormat *def1;
    UErrorCode status = U_ZERO_ERROR;
    int32_t value = 0;
    UChar ret[30];

    ctest_setTimeZone(NULL, &status);

    log_verbose("Testing format and parse\n");

    str=(UChar*)malloc(sizeof(UChar) * 25);
    u_uastrcpy(str, "disturbance in force");
    tzID=(UChar*)malloc(sizeof(UChar) * 4);
    u_uastrcpy(tzID, "PST");
    cal=ucal_open(tzID, u_strlen(tzID), "en_US", UCAL_TRADITIONAL, &status);
    if(U_FAILURE(status)){
        log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status) );
    }
    ucal_setDateTime(cal, 1999, UCAL_MARCH, 18, 0, 0, 0, &status);
    d1=ucal_getMillis(cal, &status);
    if(U_FAILURE(status)){
            log_data_err("Error: failure in get millis: %s - (Are you missing data?)\n", myErrorName(status) );
    }
    
    log_verbose("\nTesting with pattern test#4");
    u_uastrcpy(pattern, "On {0, date, long}, there was a {1} on planet {2,number,integer}");
    u_uastrcpy(expected, "On March 18, 1999, there was a disturbance in force on planet 7"); 
    resultlength=1;
    result=(UChar*)malloc(sizeof(UChar) * resultlength);
    resultLengthOut=u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
    if(status==U_BUFFER_OVERFLOW_ERROR)
    {
        status=U_ZERO_ERROR;
        resultlength=resultLengthOut+1;
        result=(UChar*)realloc(result, sizeof(UChar) * resultlength);
        u_formatMessage( "en_US", pattern, u_strlen(pattern), result, resultlength, &status, d1, str, 7);
        
    }
    if(U_FAILURE(status)){
        log_data_err("ERROR: failure in message format test#4: %s (Are you missing data?)\n", myErrorName(status));
    }
    else if(u_strcmp(result, expected)==0)
        log_verbose("PASS: MessagFormat successful on test#4\n");
    else{
        log_err("FAIL: Error in MessageFormat on test#4\n GOT: %s EXPECTED: %s\n", austrdup(result),
            austrdup(expected) );
    }
    
    
    /*try to parse this and check*/
    log_verbose("\nTesting the parse Message test#5\n");

    u_parseMessage("en_US", pattern, u_strlen(pattern), result, u_strlen(result), &status, &d, ret, &value);
    if(U_FAILURE(status)){
        log_data_err("ERROR: error in parsing: test#5: %s (Are you missing data?)\n", myErrorName(status));
    }
    else if(value!=7 && u_strcmp(str,ret)!=0)
        log_err("FAIL: Error in parseMessage on test#5 \n");
    else
        log_verbose("PASS: parseMessage successful on test#5\n");
        
    def1 = udat_open(UDAT_DEFAULT,UDAT_DEFAULT ,NULL, NULL, 0, NULL,0,&status);
    if(U_FAILURE(status))
    {
        log_data_err("error in creating the dateformat using short date and time style: %s (Are you missing data?)\n", myErrorName(status));
    }else{

        if(u_strcmp(myDateFormat(def1, d), myDateFormat(def1, d1))==0)
            log_verbose("PASS: parseMessage successful test#5\n");
        else{
            log_err("FAIL: parseMessage didn't parse the date successfully\n GOT: %s EXPECTED %s\n", 
                austrdup(myDateFormat(def1,d)), austrdup(myDateFormat(def1,d1)) );
        }
    }
    udat_close(def1);
    ucal_close(cal);

    free(result);
    free(str);
    free(tzID);
    
    ctest_resetTimeZone();
}
Ejemplo n.º 20
0
/**
 * @bug 4056591
 * Verify the function of the [s|g]et2DigitYearStart() API.
 */
void Test4056591()
{
    int i;
    UCalendar *cal;
    UDateFormat *def;
    UDate start,exp,got;
    UChar s[10];
    UChar *gotdate, *expdate;
    UChar pat[10];
    UDate d[4];
    UErrorCode status = U_ZERO_ERROR;
    const char* strings[] = {
        "091225",
        "091224",
        "611226",
        "991227"
    };

    log_verbose("Testing s[get] 2 digit year start regressively\n");
    cal=ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &status);
    if(U_FAILURE(status)) {
        log_data_err("error in ucal_open caldef : %s - (Are you missing data?)\n", myErrorName(status));
        return;
    }
    ucal_setDateTime(cal, 1809, UCAL_DECEMBER, 25, 17, 40, 30, &status);
    d[0]=ucal_getMillis(cal, &status);
    if(U_FAILURE(status)) {
        log_err("Error: failure in get millis: %s\n", myErrorName(status));
    }
    ucal_setDateTime(cal, 1909, UCAL_DECEMBER, 24, 17, 40, 30, &status);
    d[1]=ucal_getMillis(cal, &status);
    ucal_setDateTime(cal, 1861, UCAL_DECEMBER, 26, 17, 40, 30, &status);
    d[2]=ucal_getMillis(cal, &status);
    ucal_setDateTime(cal, 1999, UCAL_DECEMBER, 27, 17, 40, 30, &status);
    d[3]=ucal_getMillis(cal, &status);


    u_uastrcpy(pat, "yyMMdd");
    def = udat_open(UDAT_IGNORE,UDAT_IGNORE,NULL, NULL, 0, pat, u_strlen(pat), &status);
    if(U_FAILURE(status))
    {
        log_err_status(status, "FAIL: error in creating the dateformat using u_openPattern(): %s\n", myErrorName(status));
        return;
    }
    start = 1800;
    udat_set2DigitYearStart(def, start, &status);
    if(U_FAILURE(status))
        log_err("ERROR: in setTwoDigitStartDate: %s\n", myErrorName(status));
    if( (udat_get2DigitYearStart(def, &status) != start))
        log_err("ERROR: get2DigitYearStart broken\n");


    for(i = 0; i < 4; ++i) {
        u_uastrcpy(s, strings[i]);
        exp = d[i];
        got = udat_parse(def, s, u_strlen(s), 0, &status);
        gotdate=myFormatit(def, got);
        expdate=myFormatit(def, exp);

        if (gotdate == NULL || expdate == NULL) {
            log_err("myFormatit failed!\n");
        }
        else if(u_strcmp(gotdate, expdate) !=0) {
            log_err("set2DigitYearStart broken for %s \n  got: %s, expected: %s\n", austrdup(s),
                    austrdup(gotdate), austrdup(expdate) );
        }
    }

    udat_close(def);
    ucal_close(cal);
}
Ejemplo n.º 21
0
static void TestDateFormatCalendar() {
    UDateFormat *date=0, *time=0, *full=0;
    UCalendar *cal=0;
    UChar buf[256];
    char cbuf[256];
    int32_t pos;
    UDate when;
    UErrorCode ec = U_ZERO_ERROR;

    ctest_setTimeZone(NULL, &ec);

    /* Create a formatter for date fields. */
    date = udat_open(UDAT_NONE, UDAT_SHORT, "en_US", NULL, 0, NULL, 0, &ec);
    if (U_FAILURE(ec)) {
        log_data_err("FAIL: udat_open(NONE, SHORT, en_US) failed with %s (Are you missing data?)\n", 
                u_errorName(ec));
        goto FAIL;
    }

    /* Create a formatter for time fields. */
    time = udat_open(UDAT_SHORT, UDAT_NONE, "en_US", NULL, 0, NULL, 0, &ec);
    if (U_FAILURE(ec)) {
        log_err("FAIL: udat_open(SHORT, NONE, en_US) failed with %s\n", 
                u_errorName(ec));
        goto FAIL;
    }

    /* Create a full format for output */
    full = udat_open(UDAT_FULL, UDAT_FULL, "en_US", NULL, 0, NULL, 0, &ec);
    if (U_FAILURE(ec)) {
        log_err("FAIL: udat_open(FULL, FULL, en_US) failed with %s\n", 
                u_errorName(ec));
        goto FAIL;
    }

    /* Create a calendar */
    cal = ucal_open(NULL, 0, "en_US", UCAL_GREGORIAN, &ec);
    if (U_FAILURE(ec)) {
        log_err("FAIL: ucal_open(en_US) failed with %s\n", 
                u_errorName(ec));
        goto FAIL;
    }

    /* Parse the date */
    ucal_clear(cal);
    u_uastrcpy(buf, "4/5/2001");
    pos = 0;
    udat_parseCalendar(date, cal, buf, -1, &pos, &ec);
    if (U_FAILURE(ec)) {
        log_err("FAIL: udat_parseCalendar(4/5/2001) failed at %d with %s\n",
                pos, u_errorName(ec));
        goto FAIL;
    }

    /* Parse the time */
    u_uastrcpy(buf, "5:45 PM");
    pos = 0;
    udat_parseCalendar(time, cal, buf, -1, &pos, &ec);
    if (U_FAILURE(ec)) {
        log_err("FAIL: udat_parseCalendar(17:45) failed at %d with %s\n",
                pos, u_errorName(ec));
        goto FAIL;
    }
    
    /* Check result */
    when = ucal_getMillis(cal, &ec);
    if (U_FAILURE(ec)) {
        log_err("FAIL: ucal_getMillis() failed with %s\n", u_errorName(ec));
        goto FAIL;
    }
    udat_format(full, when, buf, sizeof(buf), NULL, &ec);
    if (U_FAILURE(ec)) {
        log_err("FAIL: udat_format() failed with %s\n", u_errorName(ec));
        goto FAIL;
    }
    u_austrcpy(cbuf, buf);
    /* Thursday, April 5, 2001 5:45:00 PM PDT 986517900000 */
    if (when == 986517900000.0) {
        log_verbose("Ok: Parsed result: %s\n", cbuf);
    } else {
        log_err("FAIL: Parsed result: %s, exp 4/5/2001 5:45 PM\n", cbuf);
    }

 FAIL:    
    udat_close(date);
    udat_close(time);
    udat_close(full);
    ucal_close(cal);

    ctest_resetTimeZone();
}
Ejemplo n.º 22
0
/* Print out a calendar for c's current month */
static void
print_month(UCalendar *c,
            UChar *days [],
            UBool useLongNames,
            int32_t fdow,
            UErrorCode *status)
{
    int32_t width, pad, i, day;
    int32_t lens [DAY_COUNT];
    int32_t firstday, current;
    UNumberFormat *nfmt;
    UDateFormat *dfmt;
    UChar s [BUF_SIZE];
    const UChar *pat = (useLongNames ? sLongPat : sShortPat);
    int32_t len = (useLongNames ? 9 : 8);

    if(U_FAILURE(*status)) return;


    /* ========== Generate the header containing the month and year */

    /* Open a formatter with a month and year only pattern */
    dfmt = udat_open(UDAT_IGNORE,UDAT_IGNORE,NULL,NULL,0,pat, len,status);

    /* Format the date */
    udat_format(dfmt, ucal_getMillis(c, status), s, BUF_SIZE, 0, status);


    /* ========== Get the day names */
    get_days(dfmt, days, useLongNames, fdow, status);

    /* ========== Print the header */

    /* Calculate widths for justification */
    width = 6; /* 6 spaces, 1 between each day name */
    for(i = 0; i < DAY_COUNT; ++i) {
        lens[i] = u_strlen(days[i]);
        width += lens[i];
    }

    /* Print the header, centered among the day names */
    pad = width - u_strlen(s);
    indent(pad / 2, stdout);
    uprint(s, stdout, status);
    putc('\n', stdout);


    /* ========== Print the day names */

    print_days(days, stdout, status);
    putc('\n', stdout);


    /* ========== Print the calendar */

    /* Get the first of the month */
    ucal_set(c, UCAL_DATE, 1);
    firstday = ucal_get(c, UCAL_DAY_OF_WEEK, status);

    /* The day of the week for the first day of the month is based on
    1-based days of the week, which were also reordered when placed
    in the days array.  Account for this here by offsetting by the
    first day of the week for the locale, which is also 1-based. */
    firstday -= fdow;

    /* Open the formatter */
    nfmt = unum_open(UNUM_DECIMAL, NULL,0,NULL,NULL, status);

    /* Indent the correct number of spaces for the first week */
    current = firstday;
    if(current < 0)
    {
        current += 7;
    }
    for(i = 0; i < current; ++i)
        indent(lens[i] + 1, stdout);

    /* Finally, print out the days */
    day = ucal_get(c, UCAL_DATE, status);
    do {

        /* Format the current day string */
        unum_format(nfmt, day, s, BUF_SIZE, 0, status);

        /* Calculate the justification and indent */
        pad = lens[current] - u_strlen(s);
        indent(pad, stdout);

        /* Print the day number out, followed by a space */
        uprint(s, stdout, status);
        putc(' ', stdout);

        /* Update the current day */
        ++current;
        current %= DAY_COUNT;

        /* If we're at day 0 (first day of the week), insert a newline */
        if(current == 0) {
            putc('\n', stdout);
        }

        /* Go to the next day */
        ucal_add(c, UCAL_DATE, 1, status);
        day = ucal_get(c, UCAL_DATE, status);

    } while(day != 1);

    /* Output a trailing newline */
    putc('\n', stdout);

    /* Clean up */
    free_days(days);
    unum_close(nfmt);
    udat_close(dfmt);
}