internal long GetUtcOffsetFromUniversalTime(DateTime time, ref Boolean isAmbiguousLocalDst) {
// Get the daylight changes for the year of the specified time.
TimeSpan offset = new TimeSpan(m_ticksOffset);
DaylightTime daylightTime = GetDaylightChanges(time.Year);
isAmbiguousLocalDst= false;
if (daylightTime == null || daylightTime.Delta.Ticks == 0) {
return offset.Ticks;
}
// The start and end times represent the range of universal times that are in DST for that year.
// Within that there is an ambiguous hour, usually right at the end, but at the beginning in
// the unusual case of a negative daylight savings delta.
DateTime startTime = daylightTime.Start - offset;
DateTime endTime = daylightTime.End - offset - daylightTime.Delta;
DateTime ambiguousStart;
DateTime ambiguousEnd;
if (daylightTime.Delta.Ticks > 0) {
ambiguousStart = endTime - daylightTime.Delta;
ambiguousEnd = endTime;
} else {
ambiguousStart = startTime;
ambiguousEnd = startTime - daylightTime.Delta;
}
Boolean isDst = false;
if (startTime > endTime) {
// In southern hemisphere, the daylight saving time starts later in the year, and ends in the beginning of next year.
// Note, the summer in the southern hemisphere begins late in the year.
isDst = (time < endTime || time >= startTime);
}
else {
// In northern hemisphere, the daylight saving time starts in the middle of the year.
isDst = (time>=startTime && time<endTime);
}
if (isDst) {
offset += daylightTime.Delta;
// See if the resulting local time becomes ambiguous. This must be captured here or the
// DateTime will not be able to round-trip back to UTC accurately.
if (time >= ambiguousStart && time < ambiguousEnd ) {
isAmbiguousLocalDst = true;
}
}
return offset.Ticks;
}