/** * Obtains an instance of {@code ZonedDateTime} from a local date-time * using the preferred offset if possible. * <p> * The local date-time is resolved to a single instant on the time-line. * This is achieved by finding a valid offset from UTC/Greenwich for the local * date-time as defined by the {@link ZoneRules rules} of the zone ID. *<p> * In most cases, there is only one valid offset for a local date-time. * In the case of an overlap, where clocks are set back, there are two valid offsets. * If the preferred offset is one of the valid offsets then it is used. * Otherwise the earlier valid offset is used, typically corresponding to "summer". * <p> * In the case of a gap, where clocks jump forward, there is no valid offset. * Instead, the local date-time is adjusted to be later by the length of the gap. * For a typical one hour daylight savings change, the local date-time will be * moved one hour later into the offset typically corresponding to "summer". * * @param localDateTime the local date-time, not null * @param zone the time-zone, not null * @param preferredOffset the zone offset, null if no preference * @return the zoned date-time, not null */ public static ZonedDateTime ofLocal(LocalDateTime localDateTime, ZoneId zone, ZoneOffset preferredOffset) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(zone, "zone"); if (zone instanceof ZoneOffset) { return new ZonedDateTime(localDateTime, (ZoneOffset) zone, zone); } ZoneRules rules = zone.getRules(); List<ZoneOffset> validOffsets = rules.getValidOffsets(localDateTime); ZoneOffset offset; if (validOffsets.size() == 1) { offset = validOffsets.get(0); } else if (validOffsets.size() == 0) { ZoneOffsetTransition trans = rules.getTransition(localDateTime); localDateTime = localDateTime.plusSeconds(trans.getDuration().getSeconds()); offset = trans.getOffsetAfter(); } else { if (preferredOffset != null && validOffsets.contains(preferredOffset)) { offset = preferredOffset; } else { offset = Objects.requireNonNull(validOffsets.get(0), "offset"); // protect against bad ZoneRules } } return new ZonedDateTime(localDateTime, offset, zone); }
/** * Obtains an instance of {@code ZonedDateTime} strictly validating the * combination of local date-time, offset and zone ID. * <p> * This creates a zoned date-time ensuring that the offset is valid for the * local date-time according to the rules of the specified zone. * If the offset is invalid, an exception is thrown. * * @param localDateTime the local date-time, not null * @param offset the zone offset, not null * @param zone the time-zone, not null * @return the zoned date-time, not null */ public static ZonedDateTime ofStrict(LocalDateTime localDateTime, ZoneOffset offset, ZoneId zone) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(offset, "offset"); Objects.requireNonNull(zone, "zone"); ZoneRules rules = zone.getRules(); if (rules.isValidOffset(localDateTime, offset) == false) { ZoneOffsetTransition trans = rules.getTransition(localDateTime); if (trans != null && trans.isGap()) { // error message says daylight savings for simplicity // even though there are other kinds of gaps throw new DateTimeException("LocalDateTime '" + localDateTime + "' does not exist in zone '" + zone + "' due to a gap in the local time-line, typically caused by daylight savings"); } throw new DateTimeException("ZoneOffset '" + offset + "' is not valid for LocalDateTime '" + localDateTime + "' in zone '" + zone + "'"); } return new ZonedDateTime(localDateTime, offset, zone); }
public void test_NewYork_getOffsetInfo_gap() { ZoneId test = ZoneId.of("America/New_York"); final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(-5), GAP); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-5)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-4)); assertEquals(trans.getInstant(), createInstant(2008, 3, 9, 2, 0, 0, 0, ZoneOffset.ofHours(-5))); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-6)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-3)), false); assertEquals(trans.toString(), "Transition[Gap at 2008-03-09T02:00-05:00 to -04:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(-5))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
public void test_London_getOffsetInfo_gap() { ZoneRules test = europeLondon(); final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 1, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_ZERO, GAP); assertEquals(trans.isGap(), true); assertEquals(trans.isOverlap(), false); assertEquals(trans.getOffsetBefore(), OFFSET_ZERO); assertEquals(trans.getOffsetAfter(), OFFSET_PONE); assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, ZoneOffset.UTC)); assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 3, 30, 1, 0)); assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 3, 30, 2, 0)); assertEquals(trans.isValidOffset(OFFSET_ZERO), false); assertEquals(trans.isValidOffset(OFFSET_PONE), false); assertEquals(trans.isValidOffset(OFFSET_PTWO), false); assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T01:00Z to +01:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(OFFSET_ZERO)); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
public void test_London_getOffsetInfo_overlap() { ZoneRules test = europeLondon(); final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 1, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PONE, OVERLAP); assertEquals(trans.isGap(), false); assertEquals(trans.isOverlap(), true); assertEquals(trans.getOffsetBefore(), OFFSET_PONE); assertEquals(trans.getOffsetAfter(), OFFSET_ZERO); assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, ZoneOffset.UTC)); assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 10, 26, 2, 0)); assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 10, 26, 1, 0)); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); assertEquals(trans.isValidOffset(OFFSET_ZERO), true); assertEquals(trans.isValidOffset(OFFSET_PONE), true); assertEquals(trans.isValidOffset(OFFSET_PTWO), false); assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T02:00+01:00 to Z]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(OFFSET_PONE)); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
@Test public void test_compareTo_sameInstant() { ZoneOffsetTransition a = ZoneOffsetTransition.of( LocalDateTime.ofEpochSecond(23875287L, 0, OFFSET_0200), OFFSET_0200, OFFSET_0300); ZoneOffsetTransition b = ZoneOffsetTransition.of( LocalDateTime.ofEpochSecond(23875287L, 0, OFFSET_0300), OFFSET_0300, OFFSET_0200); ZoneOffsetTransition c = ZoneOffsetTransition.of( LocalDateTime.ofEpochSecond(23875287L, 0, OFFSET_0100), OFFSET_0100, OFFSET_0400); assertEquals(a.compareTo(a) == 0, true); assertEquals(a.compareTo(b) == 0, true); assertEquals(a.compareTo(c) == 0, true); assertEquals(b.compareTo(a) == 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(b.compareTo(c) == 0, true); assertEquals(c.compareTo(a) == 0, true); assertEquals(c.compareTo(b) == 0, true); assertEquals(c.compareTo(c) == 0, true); }
public void test_London_previousTransition_historic() { ZoneRules test = europeLondon(); List<ZoneOffsetTransition> trans = test.getTransitions(); ZoneOffsetTransition first = trans.get(0); assertEquals(test.previousTransition(first.getInstant()), null); assertEquals(test.previousTransition(first.getInstant().minusNanos(1)), null); for (int i = 0; i < trans.size() - 1; i++) { ZoneOffsetTransition prev = trans.get(i); ZoneOffsetTransition cur = trans.get(i + 1); assertEquals(test.previousTransition(cur.getInstant()), prev); assertEquals(test.previousTransition(prev.getInstant().plusSeconds(1)), prev); assertEquals(test.previousTransition(prev.getInstant().plusNanos(1)), prev); } }
public void test_Paris_getOffsetInfo_gap() { ZoneRules test = europeParis(); final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PONE, GAP); assertEquals(trans.isGap(), true); assertEquals(trans.isOverlap(), false); assertEquals(trans.getOffsetBefore(), OFFSET_PONE); assertEquals(trans.getOffsetAfter(), OFFSET_PTWO); assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, ZoneOffset.UTC)); assertEquals(trans.isValidOffset(OFFSET_ZERO), false); assertEquals(trans.isValidOffset(OFFSET_PONE), false); assertEquals(trans.isValidOffset(OFFSET_PTWO), false); assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T02:00+01:00 to +02:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(OFFSET_PONE)); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
public void test_Paris_getOffsetInfo_overlap() { ZoneRules test = europeParis(); final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test, dateTime, OFFSET_PTWO, OVERLAP); assertEquals(trans.isGap(), false); assertEquals(trans.isOverlap(), true); assertEquals(trans.getOffsetBefore(), OFFSET_PTWO); assertEquals(trans.getOffsetAfter(), OFFSET_PONE); assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, ZoneOffset.UTC)); assertEquals(trans.isValidOffset(OFFSET_ZERO), false); assertEquals(trans.isValidOffset(OFFSET_PONE), true); assertEquals(trans.isValidOffset(OFFSET_PTWO), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false); assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T03:00+02:00 to +01:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(OFFSET_PTWO)); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
public void test_NewYork_getOffsetInfo_gap() { ZoneRules test = americaNewYork(); final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 9, 2, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-5), GAP); assertEquals(trans.isGap(), true); assertEquals(trans.isOverlap(), false); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-5)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-4)); assertEquals(trans.getInstant(), createInstant(2008, 3, 9, 2, 0, ZoneOffset.ofHours(-5))); assertEquals(trans.isValidOffset(OFFSET_PTWO), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), false); assertEquals(trans.toString(), "Transition[Gap at 2008-03-09T02:00-05:00 to -04:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(-5))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
public void test_Apia_jumpOverInternationalDateLine_M10_to_P14() { // transition occurred at 2011-12-30T00:00-10:00 ZoneRules test = pacificApia(); Instant instantBefore = LocalDate.of(2011, 12, 27).atStartOfDay(ZoneOffset.UTC).toInstant(); ZoneOffsetTransition trans = test.nextTransition(instantBefore); assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2011, 12, 30, 0, 0)); assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2011, 12, 31, 0, 0)); assertEquals(trans.isGap(), true); assertEquals(trans.isOverlap(), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-10)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(+14)), false); assertEquals(trans.getDuration(), Duration.ofHours(24)); assertEquals(trans.getInstant(), LocalDateTime.of(2011, 12, 31, 0, 0).toInstant(ZoneOffset.ofHours(+14))); ZonedDateTime zdt = ZonedDateTime.of(2011, 12, 29, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(2011, 12, 31, 1, 0)); }
public void test_London_getOffsetInfo_gap() { ZoneId test = ZoneId.of("Europe/London"); final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 1, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(0), GAP); assertEquals(trans.isGap(), true); assertEquals(trans.isOverlap(), false); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(0)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(1)); assertEquals(trans.getInstant(), dateTime.toInstant(ZoneOffset.UTC)); assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 3, 30, 1, 0)); assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 3, 30, 2, 0)); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false); assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T01:00Z to +01:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(0))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
private ZoneOffsetTransition checkOffset(ZoneRules rules, LocalDateTime dateTime, ZoneOffset offset, int type) { List<ZoneOffset> validOffsets = rules.getValidOffsets(dateTime); assertEquals(validOffsets.size(), type); assertEquals(rules.getOffset(dateTime), offset); if (type == 1) { assertEquals(validOffsets.get(0), offset); return null; } else { ZoneOffsetTransition zot = rules.getTransition(dateTime); assertNotNull(zot); assertEquals(zot.isOverlap(), type == 2); assertEquals(zot.isGap(), type == 0); assertEquals(zot.isValidOffset(offset), type == 2); return zot; } }
public void test_London_getOffsetInfo_overlap() { ZoneId test = ZoneId.of("Europe/London"); final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 1, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(1), OVERLAP); assertEquals(trans.isGap(), false); assertEquals(trans.isOverlap(), true); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(1)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(0)); assertEquals(trans.getInstant(), dateTime.toInstant(ZoneOffset.UTC)); assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(2008, 10, 26, 2, 0)); assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(2008, 10, 26, 1, 0)); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false); assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T02:00+01:00 to Z]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(1))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
@Test public void test_equals() { LocalDateTime ldtA = LocalDateTime.of(2010, 3, 31, 1, 0); ZoneOffsetTransition a1 = ZoneOffsetTransition.of(ldtA, OFFSET_0200, OFFSET_0300); ZoneOffsetTransition a2 = ZoneOffsetTransition.of(ldtA, OFFSET_0200, OFFSET_0300); LocalDateTime ldtB = LocalDateTime.of(2010, 10, 31, 1, 0); ZoneOffsetTransition b = ZoneOffsetTransition.of(ldtB, OFFSET_0300, OFFSET_0200); assertEquals(a1.equals(a1), true); assertEquals(a1.equals(a2), true); assertEquals(a1.equals(b), false); assertEquals(a2.equals(a1), true); assertEquals(a2.equals(a2), true); assertEquals(a2.equals(b), false); assertEquals(b.equals(a1), false); assertEquals(b.equals(a2), false); assertEquals(b.equals(b), true); assertEquals(a1.equals(""), false); assertEquals(a1.equals(null), false); }
public void test_Paris_getOffsetInfo_gap() { ZoneId test = ZoneId.of("Europe/Paris"); final LocalDateTime dateTime = LocalDateTime.of(2008, 3, 30, 2, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(1), GAP); assertEquals(trans.isGap(), true); assertEquals(trans.isOverlap(), false); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(1)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(2)); assertEquals(trans.getInstant(), createInstant(2008, 3, 30, 1, 0, 0, 0, ZoneOffset.UTC)); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false); assertEquals(trans.toString(), "Transition[Gap at 2008-03-30T02:00+01:00 to +02:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(1))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherDis = test.getRules().getTransition(dateTime); assertTrue(trans.equals(otherDis)); assertEquals(trans.hashCode(), otherDis.hashCode()); }
public void test_Paris_getOffsetInfo_overlap() { ZoneId test = ZoneId.of("Europe/Paris"); final LocalDateTime dateTime = LocalDateTime.of(2008, 10, 26, 2, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(2), OVERLAP); assertEquals(trans.isGap(), false); assertEquals(trans.isOverlap(), true); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(2)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(1)); assertEquals(trans.getInstant(), createInstant(2008, 10, 26, 1, 0, 0, 0, ZoneOffset.UTC)); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(0)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(1)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(3)), false); assertEquals(trans.toString(), "Transition[Overlap at 2008-10-26T03:00+02:00 to +01:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(2))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherDis = test.getRules().getTransition(dateTime); assertTrue(trans.equals(otherDis)); assertEquals(trans.hashCode(), otherDis.hashCode()); }
public void test_NewYork_getOffsetInfo_overlap() { ZoneId test = ZoneId.of("America/New_York"); final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test.getRules(), dateTime, ZoneOffset.ofHours(-4), OVERLAP); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-4)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-5)); assertEquals(trans.getInstant(), createInstant(2008, 11, 2, 2, 0, 0, 0, ZoneOffset.ofHours(-4))); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(2)), false); assertEquals(trans.toString(), "Transition[Overlap at 2008-11-02T02:00-04:00 to -05:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(-4))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getRules().getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
/** * Obtains an instance of {@code ZonedDateTime} strictly validating the * combination of local date-time, offset and zone ID. * <p> * This creates a zoned date-time ensuring that the offset is valid for the * local date-time according to the rules of the specified zone. * If the offset is invalid, an exception is thrown. * * @param localDateTime the local date-time, not null * @param offset the zone offset, not null * @param zone the time-zone, not null * @return the zoned date-time, not null * @throws DateTimeException if the combination of arguments is invalid */ public static ZonedDateTime ofStrict(LocalDateTime localDateTime, ZoneOffset offset, ZoneId zone) { Objects.requireNonNull(localDateTime, "localDateTime"); Objects.requireNonNull(offset, "offset"); Objects.requireNonNull(zone, "zone"); ZoneRules rules = zone.getRules(); if (rules.isValidOffset(localDateTime, offset) == false) { ZoneOffsetTransition trans = rules.getTransition(localDateTime); if (trans != null && trans.isGap()) { // error message says daylight savings for simplicity // even though there are other kinds of gaps throw new DateTimeException("LocalDateTime '" + localDateTime + "' does not exist in zone '" + zone + "' due to a gap in the local time-line, typically caused by daylight savings"); } throw new DateTimeException("ZoneOffset '" + offset + "' is not valid for LocalDateTime '" + localDateTime + "' in zone '" + zone + "'"); } return new ZonedDateTime(localDateTime, offset, zone); }
public void test_London_nextTransition_rulesBased() { ZoneRules test = europeLondon(); List<ZoneOffsetTransitionRule> rules = test.getTransitionRules(); List<ZoneOffsetTransition> trans = test.getTransitions(); ZoneOffsetTransition last = trans.get(trans.size() - 1); assertEquals(test.nextTransition(last.getInstant()), rules.get(0).createTransition(1998)); for (int year = 1998; year < 2010; year++) { ZoneOffsetTransition a = rules.get(0).createTransition(year); ZoneOffsetTransition b = rules.get(1).createTransition(year); ZoneOffsetTransition c = rules.get(0).createTransition(year + 1); assertEquals(test.nextTransition(a.getInstant()), b); assertEquals(test.nextTransition(b.getInstant().minusNanos(1)), b); assertEquals(test.nextTransition(b.getInstant()), c); assertEquals(test.nextTransition(c.getInstant().minusNanos(1)), c); } }
public void test_NewYork_getOffsetInfo_overlap() { ZoneRules test = americaNewYork(); final LocalDateTime dateTime = LocalDateTime.of(2008, 11, 2, 1, 0, 0, 0); ZoneOffsetTransition trans = checkOffset(test, dateTime, ZoneOffset.ofHours(-4), OVERLAP); assertEquals(trans.isGap(), false); assertEquals(trans.isOverlap(), true); assertEquals(trans.getOffsetBefore(), ZoneOffset.ofHours(-4)); assertEquals(trans.getOffsetAfter(), ZoneOffset.ofHours(-5)); assertEquals(trans.getInstant(), createInstant(2008, 11, 2, 2, 0, ZoneOffset.ofHours(-4))); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-1)), false); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-5)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHours(-4)), true); assertEquals(trans.isValidOffset(OFFSET_PTWO), false); assertEquals(trans.toString(), "Transition[Overlap at 2008-11-02T02:00-04:00 to -05:00]"); assertFalse(trans.equals(null)); assertFalse(trans.equals(ZoneOffset.ofHours(-4))); assertTrue(trans.equals(trans)); final ZoneOffsetTransition otherTrans = test.getTransition(dateTime); assertTrue(trans.equals(otherTrans)); assertEquals(trans.hashCode(), otherTrans.hashCode()); }
@Test public void test_compareTo() { ZoneOffsetTransition a = ZoneOffsetTransition.of( LocalDateTime.ofEpochSecond(23875287L - 1, 0, OFFSET_0200), OFFSET_0200, OFFSET_0300); ZoneOffsetTransition b = ZoneOffsetTransition.of( LocalDateTime.ofEpochSecond(23875287L, 0, OFFSET_0300), OFFSET_0300, OFFSET_0200); ZoneOffsetTransition c = ZoneOffsetTransition.of( LocalDateTime.ofEpochSecond(23875287L + 1, 0, OFFSET_0100), OFFSET_0100,OFFSET_0400); assertEquals(a.compareTo(a) == 0, true); assertEquals(a.compareTo(b) < 0, true); assertEquals(a.compareTo(c) < 0, true); assertEquals(b.compareTo(a) > 0, true); assertEquals(b.compareTo(b) == 0, true); assertEquals(b.compareTo(c) < 0, true); assertEquals(c.compareTo(a) > 0, true); assertEquals(c.compareTo(b) > 0, true); assertEquals(c.compareTo(c) == 0, true); }
public void test_Apia_jumpForwardOverInternationalDateLine_P12_to_M12() { // transition occurred at 1879-07-04T00:00+12:33:04 ZoneRules test = pacificApia(); Instant instantBefore = LocalDate.of(1879, 7, 2).atStartOfDay(ZoneOffset.UTC).toInstant(); ZoneOffsetTransition trans = test.nextTransition(instantBefore); assertEquals(trans.getDateTimeBefore(), LocalDateTime.of(1879, 7, 5, 0, 0)); assertEquals(trans.getDateTimeAfter(), LocalDateTime.of(1879, 7, 4, 0, 0)); assertEquals(trans.isGap(), false); assertEquals(trans.isOverlap(), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(+12, 33, 4)), true); assertEquals(trans.isValidOffset(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56)), true); assertEquals(trans.getDuration(), Duration.ofHours(-24)); assertEquals(trans.getInstant(), LocalDateTime.of(1879, 7, 4, 0, 0).toInstant(ZoneOffset.ofHoursMinutesSeconds(-11, -26, -56))); ZonedDateTime zdt = ZonedDateTime.of(1879, 7, 4, 23, 0, 0, 0, ZoneId.of("Pacific/Apia")); assertEquals(zdt.plusHours(2).toLocalDateTime(), LocalDateTime.of(1879, 7, 4, 1, 0, 0)); }
@Override public ChronoZonedDateTime<D> withEarlierOffsetAtOverlap() { ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); if (trans != null && trans.isOverlap()) { ZoneOffset earlierOffset = trans.getOffsetBefore(); if (earlierOffset.equals(offset) == false) { return new ChronoZonedDateTimeImpl<>(dateTime, earlierOffset, zone); } } return this; }