I am trying to get all offsets seen in a timezone, in an interval. Below is the function that I used to accomplish this, I know you could use TimeZoneInfo.BaseUtcOffset
to get the UTC offset
for a timezone during standard time, but there is no similar method to get one during daylight saving time unless you pass a particular DST
point of time to the GetUTCOffset()
method.
static void GetOffsets(DateTime startTime, DateTime endTime, TimeZoneInfo tz)
{
var result = new HashSet<int>();
var adjRules = tz.GetAdjustmentRules();
result.Add(tz.BaseUtcOffset);
foreach (var adjustmentRule in adjRules)
{
if ((startTime >= adjustmentRule.DateStart && startTime <= adjustmentRule.DateEnd) || (endTime >= adjustmentRule.DateStart && endTime <= adjustmentRule.DateEnd) ||
(stTime <= adjustmentRule.DateStart && endTime >= adjustmentRule.DateEnd))
{
if(adjustmentRule.DaylightDelta != TimeSpan.Zero)
{
if (!result.Contains(tz.BaseUtcOffset + adjustmentRule.DaylightDelta))
result.Add((tz.BaseUtcOffset + adjustmentRule.DaylightDelta));
}
}
}
foreach (var res in result)
{
Console.WriteLine(res);
}
}
Please let me know if there is a better way to do this.
I am trying to get all offsets seen in a timezone, in an interval.
I would strongly advise you to avoid trying to use TimeZoneInfo
directly. The adjustment rules can be surprisingly awkward for some zones in some years, as I've found to my expense.
While I'm biased, I'd suggest using Noda Time, which can wrap a TimeZoneInfo
and do the hard work for you, via BclDateTimeZone.FromTimeZoneInfo
. Your question isn't entirely clear in terms of requirements, but if you can say a bit more about what you're trying to do, I can write the appropriate Noda Time code for you.
Your initial description could be implemented with something like this:
public IEnumerable<ZoneInterval> GetZoneIntervalsInInterval
(this DateTimeZone zone, Interval interval)
{
Instant current = interval.Start;
while (current < interval.End && current != Instant.MaxValue)
{
ZoneInterval zi = zone.GetZoneInterval(current);
yield return zi;
current = zi.End;
}
}
Then:
var zone = BclDateTimeZone.FromTimeZoneInfo(tzInfo);
var offsets = zone.GetZoneIntervalsInInterval(interval)
.Select(zi => zi.WallOffset)
.Distinct();
That's assuming that you mean the same thing by "offset" as I do (namely the difference between UTC and local time).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With