I want to create a custom (non-existing) TimeZone which follows exactly the same rules as Europe/London however the only difference is that the offset should be -5 hours from UTC.
For testing purposes, this is what I was trying. How do I specify daylightsavings? Or is this implementation completely wrong?
public class MyTimeZone : DateTimeZone
{
public MyTimeZone()
: base("MyTimeZone", true, Offset.FromHours(-5), Offset.FromHours(-5))
{
}
protected override bool EqualsImpl(DateTimeZone zone)
{
if (zone.Id == "MyTimeZone")
return true;
return false;
}
public override int GetHashCode()
{
return 0001;
}
public override NodaTime.TimeZones.ZoneInterval GetZoneInterval(Instant instant)
{
return new ZoneInterval("MyTimeZone", new Instant(DateTime.MinValue.Ticks), new Instant(DateTime.MaxValue.Ticks), Offset.FromHours(-5), Offset.FromHours(-5));
}
}
This certainly isn't a terribly common scenario, but it's definitely supported. (Unlike creating your own calendar, for example.)
You'd specify daylight saving via GetZoneInterval
- that method is the key to the class. The important things to get right are:
GetZoneInterval
So for example, you could have:
public class LondonOffsetZone : DateTimeZone
{
private readonly DateTimeZone london;
// This assumes London has a minimum of +0 and a maximum of +1.
// To do it better, you'd resolve Europe/London and find *its*
// min/max, and add -5 hours to each.
public LondonOffsetZone()
: base("LondonOffset", false, Offset.FromHours(-5), Offset.FromHours(-4))
{
london = DateTimeZoneProviders.Tzdb["Europe/London"];
}
public override int GetHashCode() => RuntimeHelpers.GetHashCode(this);
// Base Equals method will have handled reference equality already.
protected override bool EqualsImpl(DateTimeZone other) => false;
public override ZoneInterval GetZoneInterval(Instant instant)
{
// Return the same zone interval, but offset by 5 hours.
var londonInterval = london.GetZoneInterval(instant);
return new ZoneInterval(
londonInterval.Name,
londonInterval.Start,
londonInterval.End,
londonInterval.WallOffset + Offset.FromHours(-5),
londonInterval.Savings);
}
}
That will fail - at least in Noda Time 2.0 - at the start and end of time, where the Start
and End
properties won't work, but it should be absolutely fine for any instant you're likely to actually encounter.
See more on this question at Stackoverflow