// This is an helper method used by the method above, do not use this on its own. private static TimeSpan GetUtcOffsetHelper (DateTime dateTime, TimeZoneInfo tz, out bool isDST) { if (dateTime.Kind == DateTimeKind.Local && tz != TimeZoneInfo.Local) throw new Exception (); isDST = false; if (tz == TimeZoneInfo.Utc) return TimeSpan.Zero; TimeSpan offset; if (tz.TryGetTransitionOffset(dateTime, out offset, out isDST)) return offset; if (dateTime.Kind == DateTimeKind.Utc) { var utcRule = tz.GetApplicableRule (dateTime); if (utcRule != null && tz.IsInDST (utcRule, dateTime)) { isDST = true; return tz.BaseUtcOffset + utcRule.DaylightDelta; } return tz.BaseUtcOffset; } DateTime stdUtcDateTime; if (!TryAddTicks (dateTime, -tz.BaseUtcOffset.Ticks, out stdUtcDateTime, DateTimeKind.Utc)) return tz.BaseUtcOffset; var tzRule = tz.GetApplicableRule (stdUtcDateTime); DateTime dstUtcDateTime = DateTime.MinValue; if (tzRule != null) { if (!TryAddTicks (stdUtcDateTime, -tzRule.DaylightDelta.Ticks, out dstUtcDateTime, DateTimeKind.Utc)) return tz.BaseUtcOffset; } if (tzRule != null && tz.IsInDST (tzRule, stdUtcDateTime) && tz.IsInDST (tzRule, dstUtcDateTime)) { isDST = true; return tz.BaseUtcOffset + tzRule.DaylightDelta; } return tz.BaseUtcOffset; }
// This is an helper method used by the method above, do not use this on its own. private static TimeSpan GetUtcOffsetHelper (DateTime dateTime, TimeZoneInfo tz, out bool isDST) { if (dateTime.Kind == DateTimeKind.Local && tz != TimeZoneInfo.Local) throw new Exception (); isDST = false; if (tz == TimeZoneInfo.Utc) return TimeSpan.Zero; TimeSpan offset; if (tz.TryGetTransitionOffset(dateTime, out offset, out isDST)) return offset; if (dateTime.Kind == DateTimeKind.Utc) { var utcRule = tz.GetApplicableRule (dateTime); if (utcRule != null && tz.IsInDST (utcRule, dateTime)) { isDST = true; return tz.BaseUtcOffset + utcRule.DaylightDelta; } return tz.BaseUtcOffset; } DateTime stdUtcDateTime; if (!TryAddTicks (dateTime, -tz.BaseUtcOffset.Ticks, out stdUtcDateTime, DateTimeKind.Utc)) return tz.BaseUtcOffset; var tzRule = tz.GetApplicableRule (stdUtcDateTime); DateTime dstUtcDateTime = DateTime.MinValue; if (tzRule != null) { if (!TryAddTicks (stdUtcDateTime, -tzRule.DaylightDelta.Ticks, out dstUtcDateTime, DateTimeKind.Utc)) return tz.BaseUtcOffset; } if (tzRule != null && tz.IsInDST (tzRule, stdUtcDateTime)) { // Replicate what .NET does when given a time which falls into the hour which is lost when // DST starts. isDST should always be true but the offset should be BaseUtcOffset without the // DST delta while in that hour. isDST = true; if (tz.IsInDST (tzRule, dstUtcDateTime)) { return tz.BaseUtcOffset + tzRule.DaylightDelta; } else { return tz.BaseUtcOffset; } } return tz.BaseUtcOffset; }