2016-09-20 3 views
2

ヨーロッパ/ロンドンとまったく同じ規則に従うカスタム(存在しない)TimeZoneを作成したいのですが、唯一の違いはオフセットがUTCから-5時間あることです。.NET NodaTimeどのようにカスタムTimeZoneを作成できますか?

テスト目的のために、これは私が試していたものです。どのように昼夜照明を指定するのですか?あるいは、この実装は完全に間違っていますか?

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)); 
     } 
    } 
+0

以前はNodaTimeを使ったことがありませんでしたが、私はあなたの 'GetHashCode'関数が完全に間違っていると伝えます。異なる値を識別するためには、比較的ユニークな値を返す必要があります。私はゾーンIDのハッシュコードを返すことをお勧めします。私の推測では、基本クラスはすでにそれのようなことをしているはずです。 –

+0

ご返信ありがとうございます。私はそれを修正することを確認します。 –

+0

NodaTimeにこれを簡単に行うためのAPIがあるとは思わないが、Jonがすぐにこれに答えてくれると確信している。 :)好奇心は、これのビジネス/アプリケーションのユースケースは何ですか?人々がカスタムタイムゾーンが必要だと言うと、私はいつも不思議です。私が経験した限り、実際の実際の使用量のほとんどは実際にはそれを必要としません。 –

答えて

2

これは確かにひどく一般的なシナリオではありませんが、間違いなくサポートされています。

GetZoneIntervalで夏時間を指定すると、そのメソッドがクラスのキーになります。権利を取得するための重要なものは以下のとおりです。オフセット最小/最大と

  • チェーンコンストラクタ呼び出します
  • GetZoneInterval
  • 平等/ハッシュコード、(あなたの最大はUTC-4、ないUTC-5になります)現時点では常にアイデンティティの平等を成立させることができます。

したがって、たとえば、あなたが持っている可能性があり:

失敗します
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); 
    } 
} 

- 少なくとも野田時間2.0に - StartEndプロパティが機能しません時間の開始と終了時に実際に遭遇する可能性のある瞬間は絶対にうまくいくはずです。

+0

もちろん、既存のtzdbゾーンのカプセル化がおそらく最も簡単です。しかし、最初から実装するためにカスタムDSTの移行日やその他のオフセット変更が実際にあった場合、どれほど複雑なのでしょうか? –

+1

@MattJohnson:既に移行瞬間がある場合は、https://github.com/nodatime/nodatime/blob/master/src/NodaTime/TimeZones/PrecalculatedDateTimeZone.cs#L78のようになります –

+1

これは時間の終了時に機能するように修正できますか?私は宇宙の終わりにレストランで食事をしながらこれを使用したいと思います。 – Amy

関連する問題