use of android.icu.util.TimeZoneRule in project j2objc by google.
the class TimeZoneRuleTest method TestGetSimpleRules.
/*
* Extract simple rules from an OlsonTimeZone and make sure the rule format matches
* the expected format.
*/
@Test
public void TestGetSimpleRules() {
long[] testTimes = new long[] { getUTCMillis(1970, Calendar.JANUARY, 1), getUTCMillis(2000, Calendar.MARCH, 31), getUTCMillis(2005, Calendar.JULY, 1), getUTCMillis(2010, Calendar.NOVEMBER, 1) };
String[] tzids = getTestZIDs();
for (int n = 0; n < testTimes.length; n++) {
long time = testTimes[n];
for (int i = 0; i < tzids.length; i++) {
BasicTimeZone tz = (BasicTimeZone) TimeZone.getTimeZone(tzids[i], TimeZone.TIMEZONE_ICU);
TimeZoneRule[] rules = tz.getSimpleTimeZoneRulesNear(time);
if (rules == null) {
errln("FAIL: Failed to extract simple rules for " + tzids[i] + " at " + time);
} else {
if (rules.length == 1) {
if (!(rules[0] instanceof InitialTimeZoneRule)) {
errln("FAIL: Unexpected rule object type is returned for " + tzids[i] + " at " + time);
}
} else if (rules.length == 3) {
if (!(rules[0] instanceof InitialTimeZoneRule) || !(rules[1] instanceof AnnualTimeZoneRule) || !(rules[2] instanceof AnnualTimeZoneRule)) {
errln("FAIL: Unexpected rule object type is returned for " + tzids[i] + " at " + time);
}
for (int idx = 1; idx <= 2; idx++) {
DateTimeRule dtr = ((AnnualTimeZoneRule) rules[idx]).getRule();
if (dtr.getTimeRuleType() != DateTimeRule.WALL_TIME) {
errln("FAIL: WALL_TIME is not used as the time rule in the time zone rule(" + idx + ") for " + tzids[i] + " at " + time);
}
if (dtr.getDateRuleType() != DateTimeRule.DOW) {
errln("FAIL: DOW is not used as the date rule in the time zone rule(" + idx + ") for " + tzids[i] + " at " + time);
}
}
} else {
errln("FAIL: Unexpected number of rules returned for " + tzids[i] + " at " + time);
}
}
}
}
}
use of android.icu.util.TimeZoneRule in project j2objc by google.
the class TimeZoneTest method createRBTZ.
private static RuleBasedTimeZone createRBTZ(BasicTimeZone btz, long start) {
TimeZoneRule[] rules = btz.getTimeZoneRules(start);
RuleBasedTimeZone rbtz = new RuleBasedTimeZone("RBTZ:btz.getID()", (InitialTimeZoneRule) rules[0]);
for (int i = 1; i < rules.length; i++) {
rbtz.addTransitionRule(rules[i]);
}
return rbtz;
}
use of android.icu.util.TimeZoneRule in project j2objc by google.
the class TimeZoneRuleTest method TestSimpleTimeZoneCoverage.
/*
* API coverage test for BasicTimeZone APIs in SimpleTimeZone
*/
@Test
public void TestSimpleTimeZoneCoverage() {
long time1 = getUTCMillis(1990, Calendar.JUNE, 1);
long time2 = getUTCMillis(2000, Calendar.JUNE, 1);
TimeZoneTransition tzt1, tzt2;
// BasicTimeZone API implementation in SimpleTimeZone
SimpleTimeZone stz1 = new SimpleTimeZone(-5 * HOUR, "GMT-5");
tzt1 = stz1.getNextTransition(time1, false);
if (tzt1 != null) {
errln("FAIL: No transition must be returned by getNextTranstion for SimpleTimeZone with no DST rule");
}
tzt1 = stz1.getPreviousTransition(time1, false);
if (tzt1 != null) {
errln("FAIL: No transition must be returned by getPreviousTransition for SimpleTimeZone with no DST rule");
}
TimeZoneRule[] tzrules = stz1.getTimeZoneRules();
if (tzrules.length != 1 || !(tzrules[0] instanceof InitialTimeZoneRule)) {
errln("FAIL: Invalid results returned by SimpleTimeZone#getTimeZoneRules");
}
// Set DST rule
// March 11
stz1.setStartRule(Calendar.MARCH, 11, 2 * HOUR);
// First Sunday in November
stz1.setEndRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2 * HOUR);
tzt1 = stz1.getNextTransition(time1, false);
if (tzt1 == null) {
errln("FAIL: Non-null transition must be returned by getNextTranstion for SimpleTimeZone with a DST rule");
} else {
String str = tzt1.toString();
if (str == null || str.length() == 0) {
errln("FAIL: TimeZoneTransition#toString returns null or empty string");
} else {
logln(str);
}
}
tzt1 = stz1.getPreviousTransition(time1, false);
if (tzt1 == null) {
errln("FAIL: Non-null transition must be returned by getPreviousTransition for SimpleTimeZone with a DST rule");
}
tzrules = stz1.getTimeZoneRules();
if (tzrules.length != 3 || !(tzrules[0] instanceof InitialTimeZoneRule) || !(tzrules[1] instanceof AnnualTimeZoneRule) || !(tzrules[2] instanceof AnnualTimeZoneRule)) {
errln("FAIL: Invalid results returned by SimpleTimeZone#getTimeZoneRules for a SimpleTimeZone with DST");
}
// Set DST start year
stz1.setStartYear(2007);
tzt1 = stz1.getPreviousTransition(time1, false);
if (tzt1 != null) {
errln("FAIL: No transition must be returned before 1990");
}
// transition after 1990-06-01
tzt1 = stz1.getNextTransition(time1, false);
// transition after 2000-06-01
tzt2 = stz1.getNextTransition(time2, false);
if (tzt1 == null || tzt2 == null || !tzt1.equals(tzt2)) {
errln("FAIL: Bad transition returned by SimpleTimeZone#getNextTransition");
}
}
use of android.icu.util.TimeZoneRule in project j2objc by google.
the class IcuZoneRulesProviderTest method assertEquivalent.
/**
* Asserts that the ICU {@link TimeZoneTransition} is equivalent to the java.time {@link
* ZoneOffsetTransition}.
*/
private static void assertEquivalent(TimeZoneTransition icuTransition, ZoneOffsetTransition jtTransition) {
if (icuTransition == null) {
assertNull(jtTransition);
return;
}
assertEquals("time of transition", Instant.ofEpochMilli(icuTransition.getTime()), jtTransition.getInstant());
TimeZoneRule from = icuTransition.getFrom();
TimeZoneRule to = icuTransition.getTo();
assertEquals("offset before", (from.getDSTSavings() + from.getRawOffset()) / 1000, jtTransition.getOffsetBefore().getTotalSeconds());
assertEquals("offset after", (to.getDSTSavings() + to.getRawOffset()) / 1000, jtTransition.getOffsetAfter().getTotalSeconds());
}
use of android.icu.util.TimeZoneRule in project j2objc by google.
the class IcuZoneRulesProvider method generateZoneRules.
/*
* This implementation is only tested with BasicTimeZone objects and depends on
* implementation details of that class:
*
* 0. TimeZone.getFrozenTimeZone() always returns a BasicTimeZone object.
* 1. The first rule is always an InitialTimeZoneRule (guaranteed by spec).
* 2. AnnualTimeZoneRules are only used as "final rules".
* 3. The final rules are either 0 or 2 AnnualTimeZoneRules
* 4. The final rules have endYear set to MAX_YEAR.
* 5. Each transition generated by the rules changes either the raw offset, the total offset
* or both.
* 6. There is a non-immense number of transitions for any rule before the final rules apply
* (enforced via the arbitrary limit defined in MAX_TRANSITIONS).
*
* Assumptions #5 and #6 are not strictly required for this code to work, but hold for the
* the data and code at the time of implementation. If they were broken they would indicate
* an incomplete understanding of how ICU TimeZoneRules are used which would probably mean that
* this code needs to be updated.
*
* These assumptions are verified using the verify() method where appropriate.
*/
static ZoneRules generateZoneRules(String zoneId) {
TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId);
// Assumption #0
verify(timeZone instanceof BasicTimeZone, zoneId, "Unexpected time zone class " + timeZone.getClass());
BasicTimeZone tz = (BasicTimeZone) timeZone;
TimeZoneRule[] rules = tz.getTimeZoneRules();
// Assumption #1
InitialTimeZoneRule initial = (InitialTimeZoneRule) rules[0];
ZoneOffset baseStandardOffset = millisToOffset(initial.getRawOffset());
ZoneOffset baseWallOffset = millisToOffset((initial.getRawOffset() + initial.getDSTSavings()));
List<ZoneOffsetTransition> standardOffsetTransitionList = new ArrayList<>();
List<ZoneOffsetTransition> transitionList = new ArrayList<>();
List<ZoneOffsetTransitionRule> lastRules = new ArrayList<>();
int preLastDstSavings = 0;
AnnualTimeZoneRule last1 = null;
AnnualTimeZoneRule last2 = null;
TimeZoneTransition transition = tz.getNextTransition(Long.MIN_VALUE, false);
int transitionCount = 1;
// "last rules" in java.time) the "break transitionLoop" will be used to exit the loop.
transitionLoop: while (transition != null) {
TimeZoneRule from = transition.getFrom();
TimeZoneRule to = transition.getTo();
boolean hadEffect = false;
if (from.getRawOffset() != to.getRawOffset()) {
standardOffsetTransitionList.add(new ZoneOffsetTransition(TimeUnit.MILLISECONDS.toSeconds(transition.getTime()), millisToOffset(from.getRawOffset()), millisToOffset(to.getRawOffset())));
hadEffect = true;
}
int fromTotalOffset = from.getRawOffset() + from.getDSTSavings();
int toTotalOffset = to.getRawOffset() + to.getDSTSavings();
if (fromTotalOffset != toTotalOffset) {
transitionList.add(new ZoneOffsetTransition(TimeUnit.MILLISECONDS.toSeconds(transition.getTime()), millisToOffset(fromTotalOffset), millisToOffset(toTotalOffset)));
hadEffect = true;
}
// Assumption #5
verify(hadEffect, zoneId, "Transition changed neither total nor raw offset.");
if (to instanceof AnnualTimeZoneRule) {
// The presence of an AnnualTimeZoneRule is taken as an indication of a final rule.
if (last1 == null) {
preLastDstSavings = from.getDSTSavings();
last1 = (AnnualTimeZoneRule) to;
// Assumption #4
verify(last1.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId, "AnnualTimeZoneRule is not permanent.");
} else {
last2 = (AnnualTimeZoneRule) to;
// Assumption #4
verify(last2.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId, "AnnualTimeZoneRule is not permanent.");
// Assumption #3
transition = tz.getNextTransition(transition.getTime(), false);
verify(transition.getTo() == last1, zoneId, "Unexpected rule after 2 AnnualTimeZoneRules.");
break transitionLoop;
}
} else {
// Assumption #2
verify(last1 == null, zoneId, "Unexpected rule after AnnualTimeZoneRule.");
}
verify(transitionCount <= MAX_TRANSITIONS, zoneId, "More than " + MAX_TRANSITIONS + " transitions.");
transition = tz.getNextTransition(transition.getTime(), false);
transitionCount++;
}
if (last1 != null) {
// Assumption #3
verify(last2 != null, zoneId, "Only one AnnualTimeZoneRule.");
lastRules.add(toZoneOffsetTransitionRule(last1, preLastDstSavings));
lastRules.add(toZoneOffsetTransitionRule(last2, last1.getDSTSavings()));
}
return ZoneRules.of(baseStandardOffset, baseWallOffset, standardOffsetTransitionList, transitionList, lastRules);
}
Aggregations