public bool TryGetNext(DateTimeOffset value, TimeZoneInfo tz, out DateTimeOffset result) { if (tz is null) { throw new ArgumentNullException(nameof(tz)); } result = DateTimeOffset.MinValue; var current = value.DateTime; var acceptCurrent = false; // vixie cron + wikipedia if (tz.IsAmbiguousTime(value)) { var periodEnd = tz.GetCurrentPeriodEnd(current); var periodEndOffset = periodEnd.Offset; var periodEndValue = periodEnd.DateTime; var otherOffset = tz.GetOtherAmbigousOffset(periodEnd); // is DST? if (otherOffset != value.Offset) { if (!TryGetNextInstant(current, acceptCurrent, out var guess)) { return(false); } if (guess < periodEndValue) { result = new DateTimeOffset(guess, periodEndOffset); return(true); } // start of the ambigous period // Magadan Standard Time has +11 as base, // but they shifted from 12 to 10 at 2014, 10, 26, 0, 0, 0 current = periodEnd.ToOffset(otherOffset).DateTime; acceptCurrent = true; } if (hasInterval) { // iterate the transition period if (!TryGetNextInstant(current, acceptCurrent, out var guess)) { return(false); } if (guess < periodEndValue) { result = new DateTimeOffset(guess, otherOffset); return(true); } } current = periodEndValue; acceptCurrent = true; } while (true) { if (!TryGetNextInstant(current, acceptCurrent, out var retval)) { return(false); } if (tz.IsInvalidTime(retval)) { current = retval; continue; } result = tz.IsAmbiguousTime(retval) ? new DateTimeOffset(retval, tz.GetCurrentPeriodEnd(retval).Offset) : new DateTimeOffset(retval, tz.GetUtcOffset(retval)); return(true); } }