private Object GetOffsetInfo(LocalDateTime dt) { if (SavingsInstantTransitions.Length == 0) { return(StandardOffsets[0]); } // check if using last rules if (LastRules.Length > 0 && dt.IsAfter(SavingsLocalTransitions[SavingsLocalTransitions.Length - 1])) { ZoneOffsetTransition[] transArray = FindTransitionArray(dt.Year); Object info = null; foreach (ZoneOffsetTransition trans in transArray) { info = FindOffsetInfo(dt, trans); if (info is ZoneOffsetTransition || info.Equals(trans.OffsetBefore)) { return(info); } } return(info); } // using historic rules int index = Arrays.BinarySearch(SavingsLocalTransitions, dt); if (index == -1) { // before first transition return(WallOffsets[0]); } if (index < 0) { // switch negative insert position to start of matched range index = -index - 2; } else if (index < SavingsLocalTransitions.Length - 1 && SavingsLocalTransitions[index].Equals(SavingsLocalTransitions[index + 1])) { // handle overlap immediately following gap index++; } if ((index & 1) == 0) { // gap or overlap LocalDateTime dtBefore = SavingsLocalTransitions[index]; LocalDateTime dtAfter = SavingsLocalTransitions[index + 1]; ZoneOffset offsetBefore = WallOffsets[index / 2]; ZoneOffset offsetAfter = WallOffsets[index / 2 + 1]; if (offsetAfter.TotalSeconds > offsetBefore.TotalSeconds) { // gap return(new ZoneOffsetTransition(dtBefore, offsetBefore, offsetAfter)); } else { // overlap return(new ZoneOffsetTransition(dtAfter, offsetBefore, offsetAfter)); } } else { // normal (neither gap or overlap) return(WallOffsets[index / 2 + 1]); } }