/** * Finds the offset info for a local date-time and transition. * * @param dt the date-time, not null * @param trans the transition, not null * @return the offset info, not null */ private Object findOffsetInfo(LocalDateTime dt, ZoneOffsetTransition trans) { LocalDateTime localTransition = trans.getDateTimeBefore(); if (trans.isGap()) { if (dt.isBefore(localTransition)) { return trans.getOffsetBefore(); } if (dt.isBefore(trans.getDateTimeAfter())) { return trans; } else { return trans.getOffsetAfter(); } } else { if (dt.isBefore(localTransition) == false) { return trans.getOffsetAfter(); } if (dt.isBefore(trans.getDateTimeAfter())) { return trans.getOffsetBefore(); } else { return trans; } } }
public boolean isExtraHour(final ZonedDateTime time) { final ZoneOffsetTransition dayTransition = time.getZone().getRules() .getTransition(time.toLocalDateTime()); return dayTransition != null && dayTransition.isOverlap() && dayTransition.getInstant() .equals(time.toInstant()); }
ZoneOffset before = wallOffsets[i]; ZoneOffset after = wallOffsets[i + 1]; ZoneOffsetTransition trans = new ZoneOffsetTransition(savingsInstantTransitions[i], before, after); if (trans.isGap()) { localTransitionList.add(trans.getDateTimeBefore()); localTransitionList.add(trans.getDateTimeAfter()); } else { localTransitionList.add(trans.getDateTimeAfter()); localTransitionList.add(trans.getDateTimeBefore());
/** * Gets the valid offsets during this transition. * <p> * A gap will return an empty list, while an overlap will return both offsets. * * @return the list of valid offsets */ List<ZoneOffset> getValidOffsets() { if (isGap()) { return Collections.emptyList(); } return Arrays.asList(getOffsetBefore(), getOffsetAfter()); }
LocalDateTime ldt = LocalDateTime.of(2015, 3, 29, 2, 30, 0, 0); ZoneRules rules = ZoneId.of("Europe/Berlin").getRules(); ZoneOffsetTransition conflict = rules.getTransition(ldt); if (conflict != null && conflict.isGap()) { ldt = conflict.getDateTimeAfter(); } System.out.println(ldt); // 2015-03-29T03:00
/** * Gets the duration of the transition in seconds. * * @return the duration in seconds */ private int getDurationSeconds() { return getOffsetAfter().getTotalSeconds() - getOffsetBefore().getTotalSeconds(); }
this.standardOffsets[0] = baseStandardOffset; for (int i = 0; i < standardOffsetTransitionList.size(); i++) { this.standardTransitions[i] = standardOffsetTransitionList.get(i).toEpochSecond(); this.standardOffsets[i + 1] = standardOffsetTransitionList.get(i).getOffsetAfter(); localTransitionOffsetList.add(baseWallOffset); for (ZoneOffsetTransition trans : transitionList) { if (trans.isGap()) { localTransitionList.add(trans.getDateTimeBefore()); localTransitionList.add(trans.getDateTimeAfter()); } else { localTransitionList.add(trans.getDateTimeAfter()); localTransitionList.add(trans.getDateTimeBefore()); localTransitionOffsetList.add(trans.getOffsetAfter()); this.savingsInstantTransitions[i] = transitionList.get(i).getInstant().getEpochSecond();
for (TZRule rule : window.ruleList) { ZoneOffsetTransition trans = rule.toTransition(loopStandardOffset, loopSavings); if (trans.toEpochSecond() > loopWindowStart.toEpochSecond(loopWindowOffset)) { new ZoneOffsetTransition( LocalDateTime.ofEpochSecond(loopWindowStart.toEpochSecond(loopWindowOffset), 0, loopStandardOffset), loopStandardOffset, window.standardOffset))); if (loopWindowOffset.equals(effectiveWallOffset) == false) { ZoneOffsetTransition trans = deduplicate( new ZoneOffsetTransition(loopWindowStart, loopWindowOffset, effectiveWallOffset)); transitionList.add(trans); if (trans.toEpochSecond() < loopWindowStart.toEpochSecond(loopWindowOffset) == false && trans.toEpochSecond() < window.createDateTimeEpochSecond(loopSavings) && trans.getOffsetBefore().equals(trans.getOffsetAfter()) == false) { transitionList.add(trans); loopSavings = rule.savingAmountSecs;
@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<D>(dateTime, earlierOffset, zone); } } return this; }
@Override public ZoneOffset getOffset(Instant instant) { long epochSec = instant.getEpochSecond(); // check if using last rules if (lastRules.length > 0 && epochSec > savingsInstantTransitions[savingsInstantTransitions.length - 1]) { int year = findYear(epochSec, wallOffsets[wallOffsets.length - 1]); ZoneOffsetTransition[] transArray = findTransitionArray(year); ZoneOffsetTransition trans = null; for (int i = 0; i < transArray.length; i++) { trans = transArray[i]; if (epochSec < trans.toEpochSecond()) { return trans.getOffsetBefore(); } } return trans.getOffsetAfter(); } // using historic rules int index = Arrays.binarySearch(savingsInstantTransitions, epochSec); if (index < 0) { // switch negative insert position to start of matched range index = -index - 2; } return wallOffsets[index + 1]; }
ZoneOffsetKey offfsetKey = ZoneOffsetKey.of(zoneTransitionRule.getOffsetBefore(), zoneTransitionRule.getOffsetAfter()); LocalDateTime start = Collections.min(e.getValue()).getDateTimeBefore(); RDate rDate = new RDate(new ParameterList(), String.format(DATE_TIME_TPL, transition.getDateTimeBefore())); observance.getProperties().add(rDate);
} else if (validOffsets.size() == 0) { ZoneOffsetTransition trans = rules.getTransition(isoLDT); localDateTime = localDateTime.plusSeconds(trans.getDuration().getSeconds()); offset = trans.getOffsetAfter(); } else { if (preferredOffset != null && validOffsets.contains(preferredOffset)) {
LocalDateTime ldt = LocalDate.of(2015, 3, 29).atTime(LocalTime.of(1, 40)); ZoneOffsetTransition conflict = ZoneId.of("Europe/London").getRules().getTransition(ldt); boolean gap = (conflict != null) && conflict.isGap(); // true
for (ZoneOffsetTransition trans : transArray) { info = findOffsetInfo(dt, trans); if (info instanceof ZoneOffsetTransition || info.equals(trans.getOffsetBefore())) { return info; if (offsetAfter.getTotalSeconds() > offsetBefore.getTotalSeconds()) { return new ZoneOffsetTransition(dtBefore, offsetBefore, offsetAfter); } else { return new ZoneOffsetTransition(dtAfter, offsetBefore, offsetAfter);
@Override public ChronoZonedDateTime<D> withLaterOffsetAtOverlap() { ZoneOffsetTransition trans = getZone().getRules().getTransition(LocalDateTime.from(this)); if (trans != null) { ZoneOffset offset = trans.getOffsetAfter(); if (offset.equals(getOffset()) == false) { return new ChronoZonedDateTimeImpl<D>(dateTime, offset, zone); } } return this; }
ZoneOffsetTransition[] transArray = findTransitionArray(year); for (ZoneOffsetTransition trans : transArray) { if (epochSec < trans.toEpochSecond()) { return trans; index += 1; // exact match, so need to add one to get the next return new ZoneOffsetTransition(savingsInstantTransitions[index], wallOffsets[index], wallOffsets[index + 1]);
ZoneId zoneId = ZoneId.of("Australia/Sydney"); ZoneRules rules = zoneId.getRules(); ZoneOffsetTransition nextTransition = rules.nextTransition(Instant.now()); System.out.println("Next transition at: " + nextTransition.getInstant().atZone(zoneId)); ZoneOffsetTransition nextNextTransition = rules.nextTransition(nextTransition.getInstant()); System.out.println("Next transition after that at: " + nextNextTransition.getInstant().atZone(zoneId));
@Override public List<ZoneOffsetTransition> getTransitions() { List<ZoneOffsetTransition> list = new ArrayList<ZoneOffsetTransition>(); for (int i = 0; i < savingsInstantTransitions.length; i++) { list.add(new ZoneOffsetTransition(savingsInstantTransitions[i], wallOffsets[i], wallOffsets[i + 1])); } return Collections.unmodifiableList(list); }
@Override public ZoneOffset getOffset(LocalDateTime localDateTime) { Object info = getOffsetInfo(localDateTime); if (info instanceof ZoneOffsetTransition) { return ((ZoneOffsetTransition) info).getOffsetBefore(); } return (ZoneOffset) info; }
@Override public int compare(ZoneOffsetTransition z1, ZoneOffsetTransition z2) { return z1.getDateTimeBefore().compareTo(z2.getDateTimeBefore()); } });