void DateIntervalFormat::setIntervalPattern(UCalendarDateFields field, const UnicodeString& intervalPattern, UBool laterDateFirst) { const UnicodeString* pattern = &intervalPattern; UBool order = laterDateFirst; // check for "latestFirst:" or "earliestFirst:" prefix int8_t prefixLength = sizeof(gLaterFirstPrefix)/sizeof(gLaterFirstPrefix[0]); int8_t earliestFirstLength = sizeof(gEarlierFirstPrefix)/sizeof(gEarlierFirstPrefix[0]); UnicodeString realPattern; if ( intervalPattern.startsWith(gLaterFirstPrefix, prefixLength) ) { order = true; intervalPattern.extract(prefixLength, intervalPattern.length() - prefixLength, realPattern); pattern = &realPattern; } else if ( intervalPattern.startsWith(gEarlierFirstPrefix, earliestFirstLength) ) { order = false; intervalPattern.extract(earliestFirstLength, intervalPattern.length() - earliestFirstLength, realPattern); pattern = &realPattern; } int32_t splitPoint = splitPatternInto2Part(*pattern); UnicodeString firstPart; UnicodeString secondPart; pattern->extract(0, splitPoint, firstPart); if ( splitPoint < pattern->length() ) { pattern->extract(splitPoint, pattern->length()-splitPoint, secondPart); } setPatternInfo(field, &firstPart, &secondPart, order); }
UnicodeString& U_EXPORT2 TimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) { if (tzID.isEmpty() || tzID.startsWith(gEtcPrefix, gEtcPrefixLen) || tzID.startsWith(gSystemVPrefix, gSystemVPrefixLen) || tzID.indexOf(gRiyadh8, gRiyadh8Len, 0) > 0) { name.setToBogus(); return name; } int32_t sep = tzID.lastIndexOf((UChar)0x2F /* '/' */); if (sep > 0 && sep + 1 < tzID.length()) { name.setTo(tzID, sep + 1); name.findAndReplace(UnicodeString((UChar)0x5f /* _ */), UnicodeString((UChar)0x20 /* space */)); } else { name.setToBogus(); } return name; }
void DateTimeStyleSet::handleParseValue(const FieldsSet* inheritFrom, int32_t field, const UnicodeString& substr, UErrorCode& status) { UnicodeString kRELATIVE_("RELATIVE_"); if(substr.startsWith(kRELATIVE_)) { UnicodeString relativeas(substr,kRELATIVE_.length()); parseValueEnum(UDBG_UDateFormatStyle, inheritFrom, field, relativeas, status); // fix relative value if(isSet(field) && U_SUCCESS(status)) { set(field, get(field) | UDAT_RELATIVE); } } else { parseValueEnum(UDBG_UDateFormatStyle, inheritFrom, field, substr, status); } }
static bool setStringArrayElement(JNIEnv* env, jobjectArray array, int i, const UnicodeString& s) { // Fill in whatever we got. We don't use the display names if they're "GMT[+-]xx:xx" // because icu4c doesn't use the up-to-date time zone transition data, so it gets these // wrong. TimeZone.getDisplayName creates accurate names on demand. // TODO: investigate whether it's worth doing that work once in the Java wrapper instead of on-demand. static const UnicodeString kGmt("GMT", 3, US_INV); if (!s.isBogus() && !s.startsWith(kGmt)) { ScopedLocalRef<jstring> javaString(env, env->NewString(s.getBuffer(), s.length())); if (javaString.get() == NULL) { return false; } env->SetObjectArrayElement(array, i, javaString.get()); } return true; }
void MessageFormatRegressionTest::Test4142938() { UnicodeString pat = CharsToUnicodeString("''Vous'' {0,choice,0#n''|1#}avez s\\u00E9lectionn\\u00E9 " "{0,choice,0#aucun|1#{0}} client{0,choice,0#s|1#|2#s} " "personnel{0,choice,0#s|1#|2#s}."); UErrorCode status = U_ZERO_ERROR; MessageFormat *mf = new MessageFormat(pat, status); failure(status, "new MessageFormat"); UnicodeString PREFIX [] = { CharsToUnicodeString("'Vous' n'avez s\\u00E9lectionn\\u00E9 aucun clients personnels."), CharsToUnicodeString("'Vous' avez s\\u00E9lectionn\\u00E9 "), CharsToUnicodeString("'Vous' avez s\\u00E9lectionn\\u00E9 ") }; UnicodeString SUFFIX [] = { UnicodeString(), UNICODE_STRING(" client personnel.", 18), UNICODE_STRING(" clients personnels.", 20) }; for (int i=0; i<3; i++) { UnicodeString out; //out = mf->format(new Object[]{new Integer(i)}); Formattable objs [] = { Formattable((int32_t)i) }; FieldPosition pos(FieldPosition::DONT_CARE); out = mf->format(objs, 1, out, pos, status); if (!failure(status, "mf->format", TRUE)) { if (SUFFIX[i] == "") { if (out != PREFIX[i]) errln((UnicodeString)"" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\""); } else { if (!out.startsWith(PREFIX[i]) || !out.endsWith(SUFFIX[i])) errln((UnicodeString)"" + i + ": Got \"" + out + "\"; Want \"" + PREFIX[i] + "\"...\"" + SUFFIX[i] + "\""); } } } delete mf; }
void RuleBasedNumberFormat::setDefaultRuleSet(const UnicodeString& ruleSetName, UErrorCode& status) { if (U_SUCCESS(status)) { if (ruleSetName.isEmpty()) { if (localizations) { UnicodeString name(TRUE, localizations->getRuleSetName(0), -1); defaultRuleSet = findRuleSet(name, status); } else { initDefaultRuleSet(); } } else if (ruleSetName.startsWith(UNICODE_STRING_SIMPLE("%%"))) { status = U_ILLEGAL_ARGUMENT_ERROR; } else { NFRuleSet* result = findRuleSet(ruleSetName, status); if (result != NULL) { defaultRuleSet = result; } } } }
void DataDrivenCalendarTest::testOps(TestData *testData, const DataMap * /*settings*/) { UErrorCode status = U_ZERO_ERROR; UBool useDate = FALSE; // TODO UnicodeString kMILLIS("MILLIS="); // TODO: static UDate fromDate = 0; // TODO UDate toDate = 0; const DataMap *currentCase= NULL; char toCalLoc[256] = ""; // TODO: static strings? const UnicodeString kADD("add", ""); const UnicodeString kROLL("roll", ""); // Get 'from' time CalendarFieldsSet fromSet, toSet, paramsSet, diffSet; SimpleDateFormat fmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status); if (U_FAILURE(status)) { dataerrln("FAIL: Couldn't create SimpleDateFormat: %s", u_errorName(status)); return; } // Start the processing int n = 0; while (testData->nextCase(currentCase, status)) { ++n; Calendar *toCalendar= NULL; Calendar *fromCalendar= NULL; // load parameters char theCase[200]; sprintf(theCase, "[case %d]", n); UnicodeString caseString(theCase, ""); // build to calendar // Headers { "locale","from","operation","params","to" } // #1 locale const char *param = "locale"; UnicodeString locale; UnicodeString testSetting = currentCase->getString(param, status); if (U_FAILURE(status)) { errln(caseString+": Unable to get param '"+param+"' " + UnicodeString(" - ")); continue; } testSetting.extract(0, testSetting.length(), toCalLoc, (const char*)0); fromCalendar = Calendar::createInstance(toCalLoc, status); if (U_FAILURE(status)) { errln(caseString+": Unable to instantiate calendar for " +testSetting); continue; } fromSet.clear(); // #2 'from' info param = "from"; UnicodeString from = testSetting=currentCase->getString(param, status); if (U_FAILURE(status)) { errln(caseString+": Unable to get parameter '"+param+"' " + UnicodeString(" - ")); continue; } if(from.startsWith(kMILLIS)){ UnicodeString millis = UnicodeString(from, kMILLIS.length()); useDate = TRUE; fromDate = udbg_stod(millis); } else if(fromSet.parseFrom(testSetting, status)<0 || U_FAILURE(status)){ errln(caseString+": Failed to parse '"+param+"' parameter: " +testSetting); continue; } // #4 'operation' info param = "operation"; UnicodeString operation = testSetting=currentCase->getString(param, status); if (U_FAILURE(status)) { errln(caseString+": Unable to get parameter '"+param+"' " + UnicodeString(" - ")); continue; } if (U_FAILURE(status)) { errln(caseString+": Failed to parse '"+param+"' parameter: " +testSetting); continue; } paramsSet.clear(); // #3 'params' info param = "params"; UnicodeString params = testSetting =currentCase->getString(param, status); if (U_FAILURE(status)) { errln(caseString+": Unable to get parameter '"+param+"' " + UnicodeString(" - ")); continue; } paramsSet.parseFrom(testSetting, status); // parse with inheritance. if (U_FAILURE(status)) { errln(caseString+": Failed to parse '"+param+"' parameter: " +testSetting); continue; } toSet.clear(); // #4 'to' info param = "to"; UnicodeString to = testSetting=currentCase->getString(param, status); if (U_FAILURE(status)) { errln(caseString+": Unable to get parameter '"+param+"' " + UnicodeString(" - ")); continue; } if(to.startsWith(kMILLIS)){ UnicodeString millis = UnicodeString(to, kMILLIS.length()); useDate = TRUE; toDate = udbg_stod(millis); } else if(toSet.parseFrom(testSetting, &fromSet, status)<0 || U_FAILURE(status)){ errln(caseString+": Failed to parse '"+param+"' parameter: " +testSetting); continue; } UnicodeString caseContentsString = locale+": from "+from+": " +operation +" [[[ "+params+" ]]] >>> "+to; logln(caseString+": "+caseContentsString); // ------ // now, do it. /// prepare calendar if(useDate){ fromCalendar->setTime(fromDate, status); if (U_FAILURE(status)) { errln(caseString+" FAIL: Failed to set time on Source calendar: " + u_errorName(status)); return; } } else { fromSet.setOnCalendar(fromCalendar, status); if (U_FAILURE(status)) { errln(caseString+" FAIL: Failed to set on Source calendar: " + u_errorName(status)); return; } } diffSet.clear(); // Is the calendar sane after being set? if (!fromSet.matches(fromCalendar, diffSet, status)) { UnicodeString diffs = diffSet.diffFrom(fromSet, status); errln((UnicodeString)"FAIL: "+caseString +", SET SOURCE calendar was not set: Differences: "+ diffs +"', status: "+ u_errorName(status)); } else if (U_FAILURE(status)) { errln("FAIL: "+caseString+" SET SOURCE calendar Failed to match: " +u_errorName(status)); } else { logln("PASS: "******" SET SOURCE calendar match."); } // to calendar - copy of from calendar toCalendar = fromCalendar->clone(); /// perform op for (int q=0; q<UCAL_FIELD_COUNT; q++) { if (paramsSet.isSet((UCalendarDateFields)q)) { if (operation == kROLL) { toCalendar->roll((UCalendarDateFields)q, paramsSet.get((UCalendarDateFields)q), status); } else if (operation == kADD) { toCalendar->add((UCalendarDateFields)q, paramsSet.get((UCalendarDateFields)q), status); } else { errln(caseString+ " FAIL: unknown operation "+ operation); } logln(operation + " of "+ paramsSet.get((UCalendarDateFields)q) +" -> "+u_errorName(status)); } } if (U_FAILURE(status)) { errln(caseString+" FAIL: after "+operation+" of "+params+" -> " +u_errorName(status)); continue; } // now - what's the result? diffSet.clear(); if(useDate){ if(!(toCalendar->getTime(status)==toDate) || U_FAILURE(status)){ errln("FAIL: "+caseString+" Match operation had an error: " +u_errorName(status)); }else{ logln(caseString + " SUCCESS: got=expected="+toDate); logln("PASS: "******" matched!"); } } else if (!toSet.matches(toCalendar, diffSet, status)) { UnicodeString diffs = diffSet.diffFrom(toSet, status); errln((UnicodeString)"FAIL: "+caseString+" - , "+caseContentsString +" Differences: "+ diffs +"', status: " + u_errorName(status)); }else if (U_FAILURE(status)) { errln("FAIL: "+caseString+" Match operation had an error: " +u_errorName(status)); }else { logln("PASS: "******" matched!"); } delete fromCalendar; delete toCalendar; } }
UBool TimeZone::parseCustomID(const UnicodeString& id, int32_t& sign, int32_t& hour, int32_t& min, int32_t& sec) { static const int32_t kParseFailed = -99999; NumberFormat* numberFormat = 0; UnicodeString idUppercase = id; idUppercase.toUpper(); if (id.length() > GMT_ID_LENGTH && idUppercase.startsWith(GMT_ID)) { ParsePosition pos(GMT_ID_LENGTH); sign = 1; hour = 0; min = 0; sec = 0; if (id[pos.getIndex()] == MINUS /*'-'*/) { sign = -1; } else if (id[pos.getIndex()] != PLUS /*'+'*/) { return FALSE; } pos.setIndex(pos.getIndex() + 1); UErrorCode success = U_ZERO_ERROR; numberFormat = NumberFormat::createInstance(success); if(U_FAILURE(success)){ return FALSE; } numberFormat->setParseIntegerOnly(TRUE); // Look for either hh:mm, hhmm, or hh int32_t start = pos.getIndex(); Formattable n(kParseFailed); numberFormat->parse(id, n, pos); if (pos.getIndex() == start) { delete numberFormat; return FALSE; } hour = n.getLong(); if (pos.getIndex() < id.length()) { if (pos.getIndex() - start > 2 || id[pos.getIndex()] != COLON) { delete numberFormat; return FALSE; } // hh:mm pos.setIndex(pos.getIndex() + 1); int32_t oldPos = pos.getIndex(); n.setLong(kParseFailed); numberFormat->parse(id, n, pos); if ((pos.getIndex() - oldPos) != 2) { // must be 2 digits delete numberFormat; return FALSE; } min = n.getLong(); if (pos.getIndex() < id.length()) { if (id[pos.getIndex()] != COLON) { delete numberFormat; return FALSE; } // [:ss] pos.setIndex(pos.getIndex() + 1); oldPos = pos.getIndex(); n.setLong(kParseFailed); numberFormat->parse(id, n, pos); if (pos.getIndex() != id.length() || (pos.getIndex() - oldPos) != 2) { delete numberFormat; return FALSE; } sec = n.getLong(); } } else { // Supported formats are below - // // HHmmss // Hmmss // HHmm // Hmm // HH // H int32_t length = pos.getIndex() - start; if (length <= 0 || 6 < length) { // invalid length delete numberFormat; return FALSE; } switch (length) { case 1: case 2: // already set to hour break; case 3: case 4: min = hour % 100; hour /= 100; break; case 5: case 6: sec = hour % 100; min = (hour/100) % 100; hour /= 10000; break; } } delete numberFormat; if (hour > kMAX_CUSTOM_HOUR || min > kMAX_CUSTOM_MIN || sec > kMAX_CUSTOM_SEC) { return FALSE; } return TRUE; } return FALSE; }
/** * Fills completeStatus with a human-friendly version of the symbol table error */ static void HandleAutoCompletionPhpStatus(const t4p::SymbolTableMatchErrorClass& error, const UnicodeString& lastExpression, const pelet::VariableClass& parsedVariable, const pelet::ScopeClass& variableScope, const std::vector<t4p::PhpTagClass>& autoCompletionResourceMatches, wxString& completeStatus) { if (lastExpression.isEmpty()) { completeStatus = _("Nothing to complete"); } else if (lastExpression.startsWith(UNICODE_STRING_SIMPLE("$")) && parsedVariable.ChainList.size() <= 1) { completeStatus = _("No matching variables for: "); completeStatus += t4p::IcuToWx(lastExpression); completeStatus += _(" in scope: "); completeStatus += t4p::IcuToWx(variableScope.ClassName); completeStatus += _("::"); completeStatus += t4p::IcuToWx(variableScope.MethodName); } else if (parsedVariable.ChainList.size() == 1) { completeStatus = _("No matching class, function, define, or keyword for: \""); completeStatus += t4p::IcuToWx(lastExpression); completeStatus += wxT("\""); } else if (autoCompletionResourceMatches.empty()) { if (t4p::SymbolTableMatchErrorClass::PARENT_ERROR == error.Type) { completeStatus = _("parent not valid for scope: "); completeStatus += t4p::IcuToWx(variableScope.ClassName); completeStatus += _("::"); completeStatus += t4p::IcuToWx(variableScope.MethodName); } else if (t4p::SymbolTableMatchErrorClass::STATIC_ERROR == error.Type) { completeStatus = _("Cannot access protected or private static member \""); completeStatus += t4p::IcuToWx(error.ErrorLexeme); completeStatus += _("\" in class: "); completeStatus += t4p::IcuToWx(error.ErrorClass); } else if (t4p::SymbolTableMatchErrorClass::TYPE_RESOLUTION_ERROR == error.Type) { completeStatus = _("Could not resolve type for \""); completeStatus += t4p::IcuToWx(error.ErrorLexeme); completeStatus += wxT("\""); } else if (t4p::SymbolTableMatchErrorClass::UNKNOWN_RESOURCE == error.Type) { if (!parsedVariable.ChainList.empty() && parsedVariable.ChainList[0].Name == UNICODE_STRING_SIMPLE("$this")) { completeStatus = _("No public, protected, or private member matches for \""); } else { completeStatus = _("No public member matches for \""); } completeStatus += t4p::IcuToWx(error.ErrorLexeme); completeStatus += _("\" in class: "); completeStatus += t4p::IcuToWx(error.ErrorClass); } else if (t4p::SymbolTableMatchErrorClass::UNKNOWN_STATIC_RESOURCE == error.Type) { completeStatus = _("No static member matches for \""); completeStatus += t4p::IcuToWx(error.ErrorLexeme); completeStatus += _("\" in class: "); completeStatus += t4p::IcuToWx(error.ErrorClass); } else if (t4p::SymbolTableMatchErrorClass::VISIBILITY_ERROR == error.Type) { completeStatus = _("Cannot access protected or private member \""); completeStatus += t4p::IcuToWx(error.ErrorLexeme); completeStatus += _("\" in class: "); completeStatus += t4p::IcuToWx(error.ErrorClass); } else if (t4p::SymbolTableMatchErrorClass::ARRAY_ERROR == error.Type && !error.ErrorClass.isEmpty()) { completeStatus = _("Cannot use object operator for array returned by \""); completeStatus += t4p::IcuToWx(error.ErrorClass); completeStatus += _("::"); completeStatus += t4p::IcuToWx(error.ErrorLexeme); } else if (t4p::SymbolTableMatchErrorClass::ARRAY_ERROR == error.Type) { completeStatus = _("Cannot use object operator for array variable "); completeStatus += t4p::IcuToWx(error.ErrorLexeme); } else if (t4p::SymbolTableMatchErrorClass::PRIMITIVE_ERROR == error.Type && !error.ErrorClass.isEmpty()) { completeStatus = _("Cannot use object operator for primitive returned by \""); completeStatus += t4p::IcuToWx(error.ErrorClass); completeStatus += _("::"); completeStatus += t4p::IcuToWx(error.ErrorLexeme); } else if (t4p::SymbolTableMatchErrorClass::PRIMITIVE_ERROR == error.Type) { completeStatus = _("Cannot use object operator for primitive variable \""); completeStatus += t4p::IcuToWx(error.ErrorLexeme); } } }
void DataDrivenFormatTest::testConvertDate(TestData *testData, const DataMap * /* settings */, UBool fmt) { UnicodeString kPATTERN("PATTERN="); // TODO: static UnicodeString kMILLIS("MILLIS="); // TODO: static UnicodeString kRELATIVE_MILLIS("RELATIVE_MILLIS="); // TODO: static UnicodeString kRELATIVE_ADD("RELATIVE_ADD:"); // TODO: static UErrorCode status = U_ZERO_ERROR; SimpleDateFormat basicFmt(UnicodeString("EEE MMM dd yyyy / YYYY'-W'ww-ee"), status); if (U_FAILURE(status)) { dataerrln("FAIL: Couldn't create basic SimpleDateFormat: %s", u_errorName(status)); return; } const DataMap *currentCase= NULL; // Start the processing int n = 0; while (testData->nextCase(currentCase, status)) { char calLoc[256] = ""; DateTimeStyleSet styleSet; UnicodeString pattern; UBool usePattern = FALSE; (void)usePattern; // Suppress unused warning. CalendarFieldsSet fromSet; UDate fromDate = 0; UBool useDate = FALSE; UDate now = Calendar::getNow(); ++n; char theCase[200]; sprintf(theCase, "case %d:", n); UnicodeString caseString(theCase, ""); // load params UnicodeString locale = currentCase->getString("locale", status); if (U_FAILURE(status)) { errln("case %d: No 'locale' line.", n); continue; } UnicodeString zone = currentCase->getString("zone", status); if (U_FAILURE(status)) { errln("case %d: No 'zone' line.", n); continue; } UnicodeString spec = currentCase->getString("spec", status); if(U_FAILURE(status)) { errln("case %d: No 'spec' line.", n); continue; } UnicodeString date = currentCase->getString("date", status); if(U_FAILURE(status)) { errln("case %d: No 'date' line.", n); continue; } UnicodeString expectStr= currentCase->getString("str", status); if(U_FAILURE(status)) { errln("case %d: No 'str' line.", n); continue; } DateFormat *format = NULL; // Process: 'locale' locale.extract(0, locale.length(), calLoc, (const char*)0); // default codepage. Invariant codepage doesn't have '@'! Locale loc(calLoc); if(spec.startsWith(kPATTERN)) { pattern = UnicodeString(spec,kPATTERN.length()); usePattern = TRUE; format = new SimpleDateFormat(pattern, loc, status); if(U_FAILURE(status)) { errln("case %d: could not create SimpleDateFormat from pattern: %s", n, u_errorName(status)); continue; } } else { if(styleSet.parseFrom(spec, status)<0 || U_FAILURE(status)) { errln("case %d: could not parse spec as style fields: %s", n, u_errorName(status)); continue; } format = DateFormat::createDateTimeInstance((DateFormat::EStyle)styleSet.getDateStyle(), (DateFormat::EStyle)styleSet.getTimeStyle(), loc); if(format == NULL ) { errln("case %d: could not create SimpleDateFormat from styles.", n); continue; } } Calendar *cal = Calendar::createInstance(loc, status); if(U_FAILURE(status)) { errln("case %d: could not create calendar from %s", n, calLoc); } if (zone.length() > 0) { TimeZone * tz = TimeZone::createTimeZone(zone); cal->setTimeZone(*tz); format->setTimeZone(*tz); delete tz; } // parse 'date' if(date.startsWith(kMILLIS)) { UnicodeString millis = UnicodeString(date, kMILLIS.length()); useDate = TRUE; fromDate = udbg_stod(millis); } else if(date.startsWith(kRELATIVE_MILLIS)) { UnicodeString millis = UnicodeString(date, kRELATIVE_MILLIS.length()); useDate = TRUE; fromDate = udbg_stod(millis) + now; } else if(date.startsWith(kRELATIVE_ADD)) { UnicodeString add = UnicodeString(date, kRELATIVE_ADD.length()); // "add" is a string indicating which fields to add if(fromSet.parseFrom(add, status)<0 || U_FAILURE(status)) { errln("case %d: could not parse date as RELATIVE_ADD calendar fields: %s", n, u_errorName(status)); continue; } useDate=TRUE; cal->clear(); cal->setTime(now, status); for (int q=0; q<UCAL_FIELD_COUNT; q++) { if (fromSet.isSet((UCalendarDateFields)q)) { //int32_t oldv = cal->get((UCalendarDateFields)q, status); if (q == UCAL_DATE) { cal->add((UCalendarDateFields)q, fromSet.get((UCalendarDateFields)q), status); } else { cal->set((UCalendarDateFields)q, fromSet.get((UCalendarDateFields)q)); } //int32_t newv = cal->get((UCalendarDateFields)q, status); } } fromDate = cal->getTime(status); if(U_FAILURE(status)) { errln("case %d: could not apply date as RELATIVE_ADD calendar fields: %s", n, u_errorName(status)); continue; } } else if(fromSet.parseFrom(date, status)<0 || U_FAILURE(status)) { errln("case %d: could not parse date as calendar fields: %s", n, u_errorName(status)); continue; } // now, do it. if (fmt) { FieldPosition pos; // logln((UnicodeString)"#"+n+" "+locale+"/"+from+" >>> "+toCalLoc+"/" // +to); cal->clear(); UnicodeString output; output.remove(); if(useDate) { // cal->setTime(fromDate, status); // if(U_FAILURE(status)) { // errln("case %d: could not set time on calendar: %s", n, u_errorName(status)); // continue; // } format->format(fromDate, output, pos, status); } else { fromSet.setOnCalendar(cal, status); if(U_FAILURE(status)) { errln("case %d: could not set fields on calendar: %s", n, u_errorName(status)); continue; } format->format(*cal, output, pos); } // check erro result from 'format' if(U_FAILURE(status)) { errln("case %d: could not format(): %s", n, u_errorName(status)); // TODO: use 'pos' } // if(pos.getBeginIndex()==0 && pos.getEndIndex()==0) { // TODO: more precise error? // errln("WARNING: case %d: format's pos returned (0,0) - error ??", n); // } if(output == expectStr) { logln(caseString+": format: SUCCESS! "+UnicodeString("expect=output=")+output); } else { UnicodeString result; UnicodeString result2; errln(caseString+": format: output!=expectStr, got " + *udbg_escape(output, &result) + " expected " + *udbg_escape(expectStr, &result2)); } } else { cal->clear(); ParsePosition pos; format->parse(expectStr,*cal,pos); if(useDate) { UDate gotDate = cal->getTime(status); if(U_FAILURE(status)) { errln(caseString+": parse: could not get time on calendar: "+UnicodeString(u_errorName(status))); continue; } if(gotDate == fromDate) { logln(caseString+": parse: SUCCESS! "+UnicodeString("gotDate=parseDate=")+expectStr); } else { UnicodeString expectDateStr, gotDateStr; basicFmt.format(fromDate,expectDateStr); basicFmt.format(gotDate,gotDateStr); errln(caseString+": parse: FAIL. parsed '"+expectStr+"' and got "+gotDateStr+", expected " + expectDateStr); } } else { // Calendar *cal2 = cal->clone(); // cal2->clear(); // fromSet.setOnCalendar(cal2, status); if(U_FAILURE(status)) { errln("case %d: parse: could not set fields on calendar: %s", n, u_errorName(status)); continue; } CalendarFieldsSet diffSet; // diffSet.clear(); if (!fromSet.matches(cal, diffSet, status)) { UnicodeString diffs = diffSet.diffFrom(fromSet, status); errln((UnicodeString)"FAIL: "+caseString +", Differences: '"+ diffs +"', status: "+ u_errorName(status)); } else if (U_FAILURE(status)) { errln("FAIL: "+caseString+" parse SET SOURCE calendar Failed to match: " +u_errorName(status)); } else { logln("PASS: "******" parse."); } } } delete cal; delete format; } // delete basicFmt; }
/** * Parse a custom time zone identifier and return a corresponding zone. * @param id a string of the form GMT[+-]hh:mm, GMT[+-]hhmm, or * GMT[+-]hh. * @return a newly created SimpleTimeZone with the given offset and * no Daylight Savings Time, or null if the id cannot be parsed. */ TimeZone* TimeZone::createCustomTimeZone(const UnicodeString& id) { static const int32_t kParseFailed = -99999; NumberFormat* numberFormat = 0; UnicodeString idUppercase = id; idUppercase.toUpper(); if (id.length() > GMT_ID_LENGTH && idUppercase.startsWith(GMT_ID)) { ParsePosition pos(GMT_ID_LENGTH); UBool negative = FALSE; int32_t offset; if (id[pos.getIndex()] == 0x002D /*'-'*/) negative = TRUE; else if (id[pos.getIndex()] != 0x002B /*'+'*/) return 0; pos.setIndex(pos.getIndex() + 1); UErrorCode success = U_ZERO_ERROR; numberFormat = NumberFormat::createInstance(success); numberFormat->setParseIntegerOnly(TRUE); // Look for either hh:mm, hhmm, or hh int32_t start = pos.getIndex(); Formattable n(kParseFailed); numberFormat->parse(id, n, pos); if (pos.getIndex() == start) { delete numberFormat; return 0; } offset = n.getLong(); if (pos.getIndex() < id.length() && id[pos.getIndex()] == 0x003A /*':'*/) { // hh:mm offset *= 60; pos.setIndex(pos.getIndex() + 1); int32_t oldPos = pos.getIndex(); n.setLong(kParseFailed); numberFormat->parse(id, n, pos); if (pos.getIndex() == oldPos) { delete numberFormat; return 0; } offset += n.getLong(); } else { // hhmm or hh // Be strict about interpreting something as hh; it must be // an offset < 30, and it must be one or two digits. Thus // 0010 is interpreted as 00:10, but 10 is interpreted as // 10:00. if (offset < 30 && (pos.getIndex() - start) <= 2) offset *= 60; // hh, from 00 to 29; 30 is 00:30 else offset = offset % 100 + offset / 100 * 60; // hhmm } if(negative) offset = -offset; delete numberFormat; return new SimpleTimeZone(offset * 60000, CUSTOM_ID); } return 0; }