/* {{{ proto bool datefmt_set_calendar(IntlDateFormatter $mf, mixed $calendar) * Set formatter's calendar. */ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) { zval *calendar_zv; DATE_FORMAT_METHOD_INIT_VARS; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &object, IntlDateFormatter_ce_ptr, &calendar_zv) == FAILURE) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_set_calendar: unable to parse input params", 0 TSRMLS_CC); RETURN_FALSE; } DATE_FORMAT_METHOD_FETCH_OBJECT; Calendar *cal; long cal_type; bool cal_owned; Locale locale = Locale::createFromName(dfo->requested_locale); // getting the actual locale from the DateFormat is not enough // because we would have lost modifiers such as @calendar. We // must store the requested locale on object creation if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type, cal_owned TSRMLS_CC) == FAILURE) { RETURN_FALSE; } if (cal_owned) { /* a non IntlCalendar was specified, we want to keep the timezone */ TimeZone *old_timezone = fetch_datefmt(dfo)->getTimeZone().clone(); if (old_timezone == NULL) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, "datefmt_set_calendar: Out of memory when cloning calendar", 0 TSRMLS_CC); delete cal; RETURN_FALSE; } cal->adoptTimeZone(old_timezone); } else { cal = cal->clone(); if (cal == NULL) { intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, "datefmt_set_calendar: Out of memory when cloning calendar", 0 TSRMLS_CC); RETURN_FALSE; } } fetch_datefmt(dfo)->adoptCalendar(cal); dfo->calendar = cal_type; RETURN_TRUE; }
int main(int argc, char **argv) { Calendar *cal; TimeZone *zone; DateFormat *fmt; UErrorCode status = U_ZERO_ERROR; UnicodeString str; UDate date; // The languages in which we will display the date static char* LANGUAGE[] = { "en", "de", "fr" }; static const int32_t N_LANGUAGE = sizeof(LANGUAGE)/sizeof(LANGUAGE[0]); // The time zones in which we will display the time static char* TIMEZONE[] = { "America/Los_Angeles", "America/New_York", "Europe/Paris", "Europe/Berlin" }; static const int32_t N_TIMEZONE = sizeof(TIMEZONE)/sizeof(TIMEZONE[0]); // Create a calendar cal = Calendar::createInstance(status); check(status, "Calendar::createInstance"); zone = createZone("GMT"); // Create a GMT zone cal->adoptTimeZone(zone); cal->clear(); cal->set(1999, Calendar::JUNE, 4); date = cal->getTime(status); check(status, "Calendar::getTime"); for (int32_t i=0; i<N_LANGUAGE; ++i) { Locale loc(LANGUAGE[i]); // Create a formatter for DATE fmt = DateFormat::createDateInstance(DateFormat::kFull, loc); // Format the date str.remove(); fmt->format(date, str, status); // Display the formatted date string printf("Date (%s): ", LANGUAGE[i]); uprintf(escape(str)); printf("\n\n"); } printf("Exiting successfully\n"); return 0; }
void CalendarLimitTest::TestCalendarExtremeLimit() { UErrorCode status = U_ZERO_ERROR; Calendar *cal = Calendar::createInstance(status); if (failure(status, "Calendar::createInstance", TRUE)) return; cal->adoptTimeZone(TimeZone::createTimeZone("GMT")); DateFormat *fmt = DateFormat::createDateTimeInstance(); if(!fmt || !cal) { dataerrln("can't open cal and/or fmt"); return; } fmt->adoptCalendar(cal); ((SimpleDateFormat*) fmt)->applyPattern("HH:mm:ss.SSS Z, EEEE, MMMM d, yyyy G"); // This test used to test the algorithmic limits of the dates that // GregorianCalendar could handle. However, the algorithm has // been rewritten completely since then and the prior limits no // longer apply. Instead, we now do basic round-trip testing of // some extreme (but still manageable) dates. UDate m; logln("checking 1e16..1e17"); for ( m = 1e16; m < 1e17; m *= 1.1) { test(m, cal, fmt); } logln("checking -1e14..-1e15"); for ( m = -1e14; m > -1e15; m *= 1.1) { test(m, cal, fmt); } // This is 2^52 - 1, the largest allowable mantissa with a 0 // exponent in a 64-bit double UDate VERY_EARLY_MILLIS = - 4503599627370495.0; UDate VERY_LATE_MILLIS = 4503599627370495.0; // I am removing the previousDouble and nextDouble calls below for // two reasons: 1. As part of jitterbug 986, I am deprecating // these methods and removing calls to them. 2. This test is a // non-critical boundary behavior test. test(VERY_EARLY_MILLIS, cal, fmt); //test(previousDouble(VERY_EARLY_MILLIS), cal, fmt); test(VERY_LATE_MILLIS, cal, fmt); //test(nextDouble(VERY_LATE_MILLIS), cal, fmt); delete fmt; }
/** * @bug 4126678 * CANNOT REPRODUDE * * Yet another _alleged_ bug in TimeZone::getOffset(), a method that never * should have been made public. It's simply too hard to use correctly. * * The original test code failed to do the following: * (1) Call Calendar::setTime() before getting the fields! * (2) Use the right millis (as usual) for getOffset(); they were passing * in the MILLIS field, instead of the STANDARD MILLIS IN DAY. * When you fix these two problems, the test passes, as expected. */ void TimeZoneRegressionTest:: Test4126678() { UErrorCode status = U_ZERO_ERROR; Calendar *cal = Calendar::createInstance(status); if(U_FAILURE(status)) { dataerrln("Error creating calendar %s", u_errorName(status)); delete cal; return; } failure(status, "Calendar::createInstance"); TimeZone *tz = TimeZone::createTimeZone("PST"); cal->adoptTimeZone(tz); cal->set(1998, UCAL_APRIL, 5, 10, 0); if (! tz->useDaylightTime() || U_FAILURE(status)) dataerrln("We're not in Daylight Savings Time and we should be. - %s", u_errorName(status)); //cal.setTime(dt); int32_t era = cal->get(UCAL_ERA, status); int32_t year = cal->get(UCAL_YEAR, status); int32_t month = cal->get(UCAL_MONTH, status); int32_t day = cal->get(UCAL_DATE, status); int32_t dayOfWeek = cal->get(UCAL_DAY_OF_WEEK, status); int32_t millis = cal->get(UCAL_MILLISECOND, status) + (cal->get(UCAL_SECOND, status) + (cal->get(UCAL_MINUTE, status) + (cal->get(UCAL_HOUR, status) * 60) * 60) * 1000) - cal->get(UCAL_DST_OFFSET, status); failure(status, "cal->get"); int32_t offset = tz->getOffset((uint8_t)era, year, month, day, (uint8_t)dayOfWeek, millis, status); int32_t raw_offset = tz->getRawOffset(); if (offset == raw_offset) dataerrln("Offsets should match"); delete cal; }
Calendar* Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& success) { UObject* u = getService()->get(aLocale, LocaleKey::KIND_ANY, success); Calendar* c = NULL; if(U_FAILURE(success) || !u) { delete zone; if(U_SUCCESS(success)) { // Propagate some kind of err success = U_INTERNAL_PROGRAM_ERROR; } return NULL; } if(u->getDynamicClassID() == UnicodeString::getStaticClassID()) { // It's a unicode string telling us what type of calendar to load ("gregorian", etc) char tmp[200]; const UnicodeString& str = *(UnicodeString*)u; // Extract a char* out of it.. int32_t len = str.length(); if(len > sizeof(tmp)-1) { len = sizeof(tmp)-1; } str.extract(0,len,tmp); tmp[len]=0; #ifdef U_DEBUG_CALSVC // fprintf(stderr, "createInstance(%s) told to look at %s..\n", (const char*)aLocale.getName(), tmp); #endif // Create a Locale over this string Locale l(tmp); delete u; u = NULL; c = (Calendar*)getService()->get(l, LocaleKey::KIND_ANY, success); if(U_FAILURE(success) || !c) { delete zone; if(U_SUCCESS(success)) { success = U_INTERNAL_PROGRAM_ERROR; // Propagate some err } return NULL; } if(c->getDynamicClassID() == UnicodeString::getStaticClassID()) { // recursed! Second lookup returned a UnicodeString. // Perhaps DefaultCalendar{} was set to another locale. success = U_MISSING_RESOURCE_ERROR; // requested a calendar type which could NOT be found. delete c; delete zone; return NULL; } #ifdef U_DEBUG_CALSVC fprintf(stderr, "setting to locale %s\n", (const char*)aLocale.getName()); #endif c->setWeekCountData(aLocale, success); // set the correct locale (this was an indirected calendar) } else { // a calendar was returned - we assume the factory did the right thing. c = (Calendar*)u; } // Now, reset calendar to default state: c->adoptTimeZone(zone); // Set the correct time zone c->setTimeInMillis(getNow(), success); // let the new calendar have the current time. return c; }
/** Date-time artithmetic * * @param time * @param value * @param units * @param tz * @param locale * * @return POSIXst * * @version 0.5-1 (Marek Gagolewski, 2014-12-30) * @version 0.5-1 (Marek Gagolewski, 2015-03-06) tz arg added */ SEXP stri_datetime_add(SEXP time, SEXP value, SEXP units, SEXP tz, SEXP locale) { PROTECT(time = stri_prepare_arg_POSIXct(time, "time")); PROTECT(value = stri_prepare_arg_integer(value, "value")); if (!isNull(tz)) PROTECT(tz = stri_prepare_arg_string_1(tz, "tz")); else PROTECT(tz); /* needed to set tzone attrib */ R_len_t vectorize_length = stri__recycling_rule(true, 2, LENGTH(time), LENGTH(value)); const char* units_val = stri__prepare_arg_string_1_notNA(units, "units"); const char* units_opts[] = {"years", "months", "weeks", "days", "hours", "minutes", "seconds", "milliseconds", NULL}; int units_cur = stri__match_arg(units_val, units_opts); const char* locale_val = stri__prepare_arg_locale(locale, "locale", true); TimeZone* tz_val = stri__prepare_arg_timezone(tz, "tz", true/*allowdefault*/); Calendar* cal = NULL; STRI__ERROR_HANDLER_BEGIN(3) StriContainerDouble time_cont(time, vectorize_length); StriContainerInteger value_cont(value, vectorize_length); UCalendarDateFields units_field; switch (units_cur) { case 0: units_field = UCAL_YEAR; break; case 1: units_field = UCAL_MONTH; break; case 2: units_field = UCAL_WEEK_OF_YEAR; break; case 3: units_field = UCAL_DAY_OF_MONTH; break; case 4: units_field = UCAL_HOUR_OF_DAY; break; case 5: units_field = UCAL_MINUTE; break; case 6: units_field = UCAL_SECOND; break; case 7: units_field = UCAL_MILLISECOND; break; default: throw StriException(MSG__INCORRECT_MATCH_OPTION, "units"); } UErrorCode status = U_ZERO_ERROR; cal = Calendar::createInstance(locale_val, status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) cal->adoptTimeZone(tz_val); tz_val = NULL; /* The Calendar takes ownership of the TimeZone. */ SEXP ret; STRI__PROTECT(ret = Rf_allocVector(REALSXP, vectorize_length)); double* ret_val = REAL(ret); for (R_len_t i=0; i<vectorize_length; ++i) { if (time_cont.isNA(i) || value_cont.isNA(i)) { ret_val[i] = NA_REAL; continue; } status = U_ZERO_ERROR; cal->setTime((UDate)(time_cont.get(i)*1000.0), status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) status = U_ZERO_ERROR; cal->add(units_field, value_cont.get(i), status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) status = U_ZERO_ERROR; ret_val[i] = ((double)cal->getTime(status))/1000.0; STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) } if (!isNull(tz)) Rf_setAttrib(ret, Rf_ScalarString(Rf_mkChar("tzone")), tz); stri__set_class_POSIXct(ret); if (tz_val) { delete tz_val; tz_val = NULL; } if (cal) { delete cal; cal = NULL; } STRI__UNPROTECT_ALL return ret; STRI__ERROR_HANDLER_END({ if (tz_val) { delete tz_val; tz_val = NULL; } if (cal) { delete cal; cal = NULL; } }) }
/** * Get values of date-time fields * * @param time * @param locale * @param tz * * @return list * * @version 0.5-1 (Marek Gagolewski, 2015-01-01) * @version 0.5-1 (Marek Gagolewski, 2015-03-03) tz arg added */ SEXP stri_datetime_fields(SEXP time, SEXP tz, SEXP locale) { PROTECT(time = stri_prepare_arg_POSIXct(time, "time")); const char* locale_val = stri__prepare_arg_locale(locale, "locale", true); if (!isNull(tz)) PROTECT(tz = stri_prepare_arg_string_1(tz, "tz")); else PROTECT(tz); /* needed to set tzone attrib */ TimeZone* tz_val = stri__prepare_arg_timezone(tz, "tz", true/*allowdefault*/); Calendar* cal = NULL; STRI__ERROR_HANDLER_BEGIN(2) R_len_t vectorize_length = LENGTH(time); StriContainerDouble time_cont(time, vectorize_length); UErrorCode status = U_ZERO_ERROR; cal = Calendar::createInstance(locale_val, status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) cal->adoptTimeZone(tz_val); tz_val = NULL; /* The Calendar takes ownership of the TimeZone. */ SEXP ret; #define STRI__FIELDS_NUM 14 STRI__PROTECT(ret = Rf_allocVector(VECSXP, STRI__FIELDS_NUM)); for (R_len_t j=0; j<STRI__FIELDS_NUM; ++j) SET_VECTOR_ELT(ret, j, Rf_allocVector(INTSXP, vectorize_length)); for (R_len_t i=0; i<vectorize_length; ++i) { if (time_cont.isNA(i)) { for (R_len_t j=0; j<STRI__FIELDS_NUM; ++j) INTEGER(VECTOR_ELT(ret, j))[i] = NA_INTEGER; continue; } status = U_ZERO_ERROR; cal->setTime((UDate)(time_cont.get(i)*1000.0), status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) for (R_len_t j=0; j<STRI__FIELDS_NUM; ++j) { UCalendarDateFields units_field; switch (j) { case 0: units_field = UCAL_EXTENDED_YEAR; break; case 1: units_field = UCAL_MONTH; break; case 2: units_field = UCAL_DAY_OF_MONTH; break; case 3: units_field = UCAL_HOUR_OF_DAY; break; case 4: units_field = UCAL_MINUTE; break; case 5: units_field = UCAL_SECOND; break; case 6: units_field = UCAL_MILLISECOND; break; case 7: units_field = UCAL_WEEK_OF_YEAR; break; case 8: units_field = UCAL_WEEK_OF_MONTH; break; case 9: units_field = UCAL_DAY_OF_YEAR; break; case 10: units_field = UCAL_DAY_OF_WEEK; break; case 11: units_field = UCAL_HOUR; break; case 12: units_field = UCAL_AM_PM; break; case 13: units_field = UCAL_ERA; break; default: throw StriException(MSG__INCORRECT_MATCH_OPTION, "units"); } //UCAL_IS_LEAP_MONTH //UCAL_MILLISECONDS_IN_DAY -> SecondsInDay // UCAL_AM_PM -> "AM" or "PM" (localized? or factor?+index in stri_datetime_symbols) add arg use_symbols???? // UCAL_DAY_OF_WEEK -> (localized? or factor?) SUNDAY, MONDAY // UCAL_DAY_OF_YEAR ' // isWekend status = U_ZERO_ERROR; INTEGER(VECTOR_ELT(ret, j))[i] = cal->get(units_field, status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) if (units_field == UCAL_MONTH) ++INTEGER(VECTOR_ELT(ret, j))[i]; // month + 1 else if (units_field == UCAL_AM_PM) ++INTEGER(VECTOR_ELT(ret, j))[i]; // ampm + 1 else if (units_field == UCAL_ERA) ++INTEGER(VECTOR_ELT(ret, j))[i]; // era + 1 }
/** * Format date-time objects * * @param time * @param format * @param tz * @param locale * * @return character vector * * @version 0.5-1 (Marek Gagolewski, 2015-01-05) * * @version 0.5-1 (Marek Gagolewski, 2015-02-22) * use tz */ SEXP stri_datetime_format(SEXP time, SEXP format, SEXP tz, SEXP locale) { PROTECT(time = stri_prepare_arg_POSIXct(time, "time")); const char* locale_val = stri__prepare_arg_locale(locale, "locale", true); const char* format_val = stri__prepare_arg_string_1_notNA(format, "format"); // "format" may be one of: const char* format_opts[] = { "date_full", "date_long", "date_medium", "date_short", "date_relative_full", "date_relative_long", "date_relative_medium", "date_relative_short", "time_full", "time_long", "time_medium", "time_short", "time_relative_full", "time_relative_long", "time_relative_medium", "time_relative_short", "datetime_full", "datetime_long", "datetime_medium", "datetime_short", "datetime_relative_full", "datetime_relative_long", "datetime_relative_medium", "datetime_relative_short", NULL}; int format_cur = stri__match_arg(format_val, format_opts); TimeZone* tz_val = stri__prepare_arg_timezone(tz, "tz", true/*allowdefault*/); Calendar* cal = NULL; DateFormat* fmt = NULL; STRI__ERROR_HANDLER_BEGIN(1) R_len_t vectorize_length = LENGTH(time); StriContainerDouble time_cont(time, vectorize_length); UnicodeString format_str(format_val); UErrorCode status = U_ZERO_ERROR; if (format_cur >= 0) { DateFormat::EStyle style = DateFormat::kNone; switch (format_cur % 8) { case 0: style = DateFormat::kFull; break; case 1: style = DateFormat::kLong; break; case 2: style = DateFormat::kMedium; break; case 3: style = DateFormat::kShort; break; case 4: style = DateFormat::kFullRelative; break; case 5: style = DateFormat::kLongRelative; break; case 6: style = DateFormat::kMediumRelative; break; case 7: style = DateFormat::kShortRelative; break; default: style = DateFormat::kNone; break; } /* ICU 54.1: Relative time styles are not currently supported. */ switch (format_cur / 8) { case 0: fmt = DateFormat::createDateInstance(style, Locale::createFromName(locale_val)); break; case 1: fmt = DateFormat::createTimeInstance( (DateFormat::EStyle)(style & ~DateFormat::kRelative), Locale::createFromName(locale_val)); break; case 2: fmt = DateFormat::createDateTimeInstance(style, (DateFormat::EStyle)(style & ~DateFormat::kRelative), Locale::createFromName(locale_val)); break; default: fmt = NULL; break; } } else fmt = new SimpleDateFormat(format_str, Locale::createFromName(locale_val), status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) status = U_ZERO_ERROR; cal = Calendar::createInstance(locale_val, status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) cal->adoptTimeZone(tz_val); tz_val = NULL; /* The Calendar takes ownership of the TimeZone. */ SEXP ret; STRI__PROTECT(ret = Rf_allocVector(STRSXP, vectorize_length)); for (R_len_t i=0; i<vectorize_length; ++i) { if (time_cont.isNA(i)) { SET_STRING_ELT(ret, i, NA_STRING); continue; } status = U_ZERO_ERROR; cal->setTime((UDate)(time_cont.get(i)*1000.0), status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) FieldPosition pos; UnicodeString out; fmt->format(*cal, out, pos); std::string s; out.toUTF8String(s); SET_STRING_ELT(ret, i, Rf_mkCharLenCE(s.c_str(), (int)s.length(), (cetype_t)CE_UTF8)); } if (tz_val) { delete tz_val; tz_val = NULL; } if (fmt) { delete fmt; fmt = NULL; } if (cal) { delete cal; cal = NULL; } STRI__UNPROTECT_ALL return ret; STRI__ERROR_HANDLER_END({ if (tz_val) { delete tz_val; tz_val = NULL; } if (fmt) { delete fmt; fmt = NULL; } if (cal) { delete cal; cal = NULL; } }) }
/** * Parse date-time objects * * @param str * @param format * @param tz * @param lenient * @param locale * * @return character vector * * @version 0.5-1 (Marek Gagolewski, 2015-01-08) * @version 0.5-1 (Marek Gagolewski, 2015-01-11) lenient arg added * @version 0.5-1 (Marek Gagolewski, 2015-02-22) use tz * @version 0.5-1 (Marek Gagolewski, 2015-03-01) set tzone attrib on retval */ SEXP stri_datetime_parse(SEXP str, SEXP format, SEXP lenient, SEXP tz, SEXP locale) { PROTECT(str = stri_prepare_arg_string(str, "str")); const char* locale_val = stri__prepare_arg_locale(locale, "locale", true); const char* format_val = stri__prepare_arg_string_1_notNA(format, "format"); bool lenient_val = stri__prepare_arg_logical_1_notNA(lenient, "lenient"); if (!isNull(tz)) PROTECT(tz = stri_prepare_arg_string_1(tz, "tz")); else PROTECT(tz); /* needed to set tzone attrib */ // "format" may be one of: const char* format_opts[] = { "date_full", "date_long", "date_medium", "date_short", "date_relative_full", "date_relative_long", "date_relative_medium", "date_relative_short", "time_full", "time_long", "time_medium", "time_short", "time_relative_full", "time_relative_long", "time_relative_medium", "time_relative_short", "datetime_full", "datetime_long", "datetime_medium", "datetime_short", "datetime_relative_full", "datetime_relative_long", "datetime_relative_medium", "datetime_relative_short", NULL}; int format_cur = stri__match_arg(format_val, format_opts); TimeZone* tz_val = stri__prepare_arg_timezone(tz, "tz", true/*allowdefault*/); Calendar* cal = NULL; DateFormat* fmt = NULL; STRI__ERROR_HANDLER_BEGIN(2) R_len_t vectorize_length = LENGTH(str); StriContainerUTF16 str_cont(str, vectorize_length); UnicodeString format_str(format_val); UErrorCode status = U_ZERO_ERROR; if (format_cur >= 0) { DateFormat::EStyle style = DateFormat::kNone; switch (format_cur % 8) { case 0: style = DateFormat::kFull; break; case 1: style = DateFormat::kLong; break; case 2: style = DateFormat::kMedium; break; case 3: style = DateFormat::kShort; break; case 4: style = DateFormat::kFullRelative; break; case 5: style = DateFormat::kLongRelative; break; case 6: style = DateFormat::kMediumRelative; break; case 7: style = DateFormat::kShortRelative; break; default: style = DateFormat::kNone; break; } /* ICU 54.1: Relative time styles are not currently supported. */ switch (format_cur / 8) { case 0: fmt = DateFormat::createDateInstance(style, Locale::createFromName(locale_val)); break; case 1: fmt = DateFormat::createTimeInstance((DateFormat::EStyle)(style & ~DateFormat::kRelative), Locale::createFromName(locale_val)); break; case 2: fmt = DateFormat::createDateTimeInstance(style, (DateFormat::EStyle)(style & ~DateFormat::kRelative), Locale::createFromName(locale_val)); break; default: fmt = NULL; break; } } else fmt = new SimpleDateFormat(format_str, Locale::createFromName(locale_val), status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) status = U_ZERO_ERROR; cal = Calendar::createInstance(locale_val, status); STRI__CHECKICUSTATUS_THROW(status, {/* do nothing special on err */}) cal->adoptTimeZone(tz_val); tz_val = NULL; /* The Calendar takes ownership of the TimeZone. */ cal->setLenient(lenient_val); SEXP ret; STRI__PROTECT(ret = Rf_allocVector(REALSXP, vectorize_length)); for (R_len_t i=0; i<vectorize_length; ++i) { if (str_cont.isNA(i)) { REAL(ret)[i] = NA_REAL; continue; } status = U_ZERO_ERROR; ParsePosition pos; fmt->parse(str_cont.get(i), *cal, pos); if (pos.getErrorIndex() >= 0) REAL(ret)[i] = NA_REAL; else { status = U_ZERO_ERROR; REAL(ret)[i] = ((double)cal->getTime(status))/1000.0; if (U_FAILURE(status)) REAL(ret)[i] = NA_REAL; } } if (!isNull(tz)) Rf_setAttrib(ret, Rf_ScalarString(Rf_mkChar("tzone")), tz); stri__set_class_POSIXct(ret); if (tz_val) { delete tz_val; tz_val = NULL; } if (fmt) { delete fmt; fmt = NULL; } if (cal) { delete cal; cal = NULL; } STRI__UNPROTECT_ALL return ret; STRI__ERROR_HANDLER_END({ if (tz_val) { delete tz_val; tz_val = NULL; } if (fmt) { delete fmt; fmt = NULL; } if (cal) { delete cal; cal = NULL; } }) }