internal DaylightTime GetDaylightChanges (int year)
{
DateTime start = DateTime.MinValue, end = DateTime.MinValue;
TimeSpan delta = new TimeSpan ();
if (transitions != null) {
end = DateTime.MaxValue;
for (var i = transitions.Count - 1; i >= 0; i--) {
var pair = transitions [i];
DateTime ttime = pair.Key;
TimeType ttype = pair.Value;
if (ttime.Year > year)
continue;
if (ttime.Year < year)
break;
if (ttype.IsDst) {
// DaylightTime.Delta is relative to the current BaseUtcOffset.
delta = new TimeSpan (0, 0, ttype.Offset) - BaseUtcOffset;
start = ttime;
} else {
end = ttime;
}
}
// DaylightTime.Start is relative to the Standard time.
if (!TryAddTicks (start, BaseUtcOffset.Ticks, out start))
start = DateTime.MinValue;
// DaylightTime.End is relative to the DST time.
if (!TryAddTicks (end, BaseUtcOffset.Ticks + delta.Ticks, out end))
end = DateTime.MinValue;
} else {
AdjustmentRule first = null, last = null;
// Rule start/end dates are either very specific or very broad depending on the platform
// 2015-10-04..2016-04-03 - Rule for a time zone in southern hemisphere on non-Windows platforms
// 2016-03-27..2016-10-03 - Rule for a time zone in northern hemisphere on non-Windows platforms
// 0001-01-01..9999-12-31 - Rule for a time zone on Windows
foreach (var rule in GetAdjustmentRules ()) {
if (rule.DateStart.Year > year || rule.DateEnd.Year < year)
continue;
if (rule.DateStart.Year <= year && (first == null || rule.DateStart.Year > first.DateStart.Year))
first = rule;
if (rule.DateEnd.Year >= year && (last == null || rule.DateEnd.Year < last.DateEnd.Year))
last = rule;
}
if (first == null || last == null)
return new DaylightTime (new DateTime (), new DateTime (), new TimeSpan ());
start = TransitionPoint (first.DaylightTransitionStart, year);
end = TransitionPoint (last.DaylightTransitionEnd, year);
delta = first.DaylightDelta;
}
if (start == DateTime.MinValue || end == DateTime.MinValue)
return new DaylightTime (new DateTime (), new DateTime (), new TimeSpan ());
return new DaylightTime (start, end, delta);
}