void EraRules::initCurrentEra() { UDate now = ucal_getNow(); int year, month0, dom, dow, doy, mid; Grego::timeToFields(now, year, month0, dom, dow, doy, mid); int currentEncodedDate = encodeDate(year, month0 + 1 /* changes to 1-base */, dom); int eraIdx = numEras - 1; while (eraIdx > 0) { if (currentEncodedDate >= startDates[eraIdx]) { break; } eraIdx--; } // Note: current era could be before the first era. // In this case, this implementation returns the first era index (0). currentEra = eraIdx;}
/** * Compare an encoded date with another date specified by year/month/day. * @param encoded An encoded date * @param year Year of another date * @param month Month of another date * @param day Day of another date * @return -1 when encoded date is earlier, 0 when two dates are same, * and 1 when encoded date is later. */ static int32_t compareEncodedDateWithYMD(int encoded, int year, int month, int day) { if (year < MIN_ENCODED_START_YEAR) { if (encoded == MIN_ENCODED_START) { if (year > MIN_INT32 || month > 1 || day > 1) { return -1; } return 0; } else { return 1; } } else if (year > MAX_ENCODED_START_YEAR) { return -1; } else { int tmp = encodeDate(year, month, day); if (encoded < tmp) { return -1; } else if (encoded == tmp) { return 0; } else { return 1; } } }
void encodeTimestamp(ISC_TIMESTAMP& isc_ts, const IBPP::Timestamp& ts) { encodeDate(isc_ts.timestamp_date, ts); encodeTime(isc_ts.timestamp_time, ts); }
EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status) { if(U_FAILURE(status)) { return nullptr; } LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "supplementalData", &status)); ures_getByKey(rb.getAlias(), "calendarData", rb.getAlias(), &status); ures_getByKey(rb.getAlias(), calType, rb.getAlias(), &status); ures_getByKey(rb.getAlias(), "eras", rb.getAlias(), &status); if (U_FAILURE(status)) { return nullptr; } int32_t numEras = ures_getSize(rb.getAlias()); int32_t firstTentativeIdx = MAX_INT32; LocalMemory<int32_t> startDates(static_cast<int32_t *>(uprv_malloc(numEras * sizeof(int32_t)))); if (startDates.isNull()) { status = U_MEMORY_ALLOCATION_ERROR; return nullptr; } uprv_memset(startDates.getAlias(), 0 , numEras * sizeof(int32_t)); while (ures_hasNext(rb.getAlias())) { LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status)); if (U_FAILURE(status)) { return nullptr; } const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias()); char *endp; int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10); if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) { status = U_INVALID_FORMAT_ERROR; return nullptr; } if (eraIdx < 0 || eraIdx >= numEras) { status = U_INVALID_FORMAT_ERROR; return nullptr; } if (isSet(startDates[eraIdx])) { // start date of the index was already set status = U_INVALID_FORMAT_ERROR; return nullptr; } UBool hasName = TRUE; UBool hasEnd = TRUE; int32_t len; while (ures_hasNext(eraRuleRes.getAlias())) { LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status)); if (U_FAILURE(status)) { return nullptr; } const char *key = ures_getKey(res.getAlias()); if (uprv_strcmp(key, "start") == 0) { const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status); if (U_FAILURE(status)) { return nullptr; } if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) { status = U_INVALID_FORMAT_ERROR; return nullptr; } startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]); } else if (uprv_strcmp(key, "named") == 0) { const UChar *val = ures_getString(res.getAlias(), &len, &status); if (u_strncmp(val, VAL_FALSE, VAL_FALSE_LEN) == 0) { hasName = FALSE; } } else if (uprv_strcmp(key, "end") == 0) { hasEnd = TRUE; } } if (isSet(startDates[eraIdx])) { if (hasEnd) { // This implementation assumes either start or end is available, not both. // For now, just ignore the end rule. } } else { if (hasEnd) { if (eraIdx != 0) { // This implementation does not support end only rule for eras other than // the first one. status = U_INVALID_FORMAT_ERROR; return nullptr; } U_ASSERT(eraIdx == 0); startDates[eraIdx] = MIN_ENCODED_START; } else { status = U_INVALID_FORMAT_ERROR; return nullptr; } } if (hasName) { if (eraIdx >= firstTentativeIdx) { status = U_INVALID_FORMAT_ERROR; return nullptr; } } else { if (eraIdx < firstTentativeIdx) { firstTentativeIdx = eraIdx; } } } EraRules *result; if (firstTentativeIdx < MAX_INT32 && !includeTentativeEra) { result = new EraRules(startDates, firstTentativeIdx); } else { result = new EraRules(startDates, numEras); } if (result == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; } return result; }