2016-08-29 8 views
5

目的は、Nodatimeを使って1つのタイムゾーンから別のタイムゾーンに時間を変換する関数を作成することです。私は、結果が正しいかどうかについてのフィードバックだけではなく、「どのように」私がこれをしているか(本当に正しいのか、微妙な穴があるのか​​)のフィードバックを探しています。ここでこれは、Nodatimeのタイムゾーン間を変換する適切な方法ですか?

は関数である。私はそれがこのようになります呼び出します

static ZonedDateTime ConvertDateTimeToDifferentTimeZone(DateTime p_from_datetime, string p_from_zone, string p_to_zone) 
{ 
    DateTimeZone from_zone = DateTimeZoneProviders.Tzdb[p_from_zone]; 
    LocalDateTime from_local = new LocalDateTime(p_from_datetime.Year, p_from_datetime.Month, p_from_datetime.Day, p_from_datetime.Hour, p_from_datetime.Minute); 
    ZonedDateTime from_datetime = from_zone.AtStrictly(from_local); 

    var from_instant = from_datetime.ToInstant(); 

    DateTimeZone to_zone = DateTimeZoneProviders.Tzdb[p_to_zone]; 
    ZonedDateTime to_datetime = to_zone.AtStrictly(from_local); 

    var to_offset_datetime = from_instant.WithOffset(to_datetime.Offset); 

    return to_zone.AtStrictly(to_offset_datetime.LocalDateTime); 
} 

方法:

DateTime from_datetime = new DateTime(2016, 10, 15, 16, 30, 0); 
    string from_zone = "US/Central"; 
    string to_zone = "US/Eastern"; 
    var x = ConvertDateTimeToDifferentTimeZone(from_datetime, from_zone, to_zone); 

    Console.WriteLine(from_datetime.ToString() + " (" + from_zone + ") = " + " (" + x.ToString() + " (" + to_zone + ")"); 

は、私は何も見つからないか、間違って何をやっていますか?

答えて

4

私は可能な限り(および.NETの命名規則)として野田時間の種類に固執するだろう。しかし、ここでの方法のビット改良版です。ゾーン間の変換はZonedDateTime.WithZoneで行う必要があります。つまり、実際にはZonedDateTimeとの変換について質問しています。あなたは本当に、本当に代わりに野田時間タイプのDateTimeを使用する必要がある場合は、おそらくのようなものとします

public static DateTime ConvertDateTimeToDifferentTimeZone(
    DateTime fromDateTime, 
    string fromZoneId, 
    string tozoneId) 
{ 
    LocalDateTime fromLocal = LocalDateTime.FromDateTime(fromDateTime); 
    DateTimeZone fromZone = DateTimeZoneProviders.Tzdb[fromZoneId]; 
    ZonedDateTime fromZoned = fromLocal.InZoneLeniently(fromZone); 

    DateTimeZone toZone = DateTimeZoneProviders.Tzdb[toZoneId]; 
    ZonedDateTime toZoned = fromZoned.WithZone(toZone); 
    LocalDateTime toLocal = toZoned.LocalDateTime; 
    return toLocal.ToDateTimeUnspecified(); 
} 

注ここInZoneLenientlyの使用 - つまり、あなたが与えてくれた現地時刻が無効な場合のためにUTCオフセットのジャンプ(通常は夏時間のため)は、例外をスローするのではなく値を返します。詳しくは、ドキュメントを参照してください。

またはZonedDateTimeで始めるかどうかわからないため、Noda Timeを使用していた場合の方法がどのように見えるかは分かりません。たとえば、次のように指定できます。

public static LocalDateTime ConvertDateTimeToDifferentTimeZone(
    LocalDateTime fromLocal, 
    string fromZoneId, 
    string tozoneId) 
{ 
    DateTimeZone fromZone = DateTimeZoneProviders.Tzdb[fromZoneId]; 
    ZonedDateTime fromZoned = fromLocal.InZoneLeniently(fromZone); 

    DateTimeZone toZone = DateTimeZoneProviders.Tzdb[toZoneId]; 
    ZonedDateTime toZoned = fromZoned.WithZone(fromZone); 
    return toZoned.LocalDateTime; 
} 
+0

ご意見ありがとうございました。これの背景はカレンダーアプリケーションです。特定の目的は、イベント所有者が特定のカレンダーイベントのタイムゾーンとともに日付と時刻の値を入力できるようにすることです。理想的には、この情報は保存される唯一の情報ですが、オフセットを格納するのに問題が生じないようにするには問題はありません。この反対側では、イベント受取人/消費者は、選択したタイムゾーンで正確な日時を見ることができます(ブラウザーの設定または希望のタイムゾーンから取得される可能性があります)。 – CINCHAPPS

+0

@TomWesson:DSTの変更のために、存在しない、または2回起こる日付/時刻を提供している場合、何をしたいのか分かります。おそらく 'InZoneLeniently'はあなたが望むことをしますが、あなたはその決定を明示的に行います。 (オフセットを保存すると、明確にすることができます) –

+0

あなたはすばやいです.Jon、上記のコメントを編集しました。 – CINCHAPPS

1

私は方法がうまく書かれていると思います。あなたは何かを逃しているわけではありません。

static ZonedDateTime ConvertDateTimeToDifferentTimeZone(DateTime p_from_datetime, string p_from_zone, string p_to_zone) 
{ 
    DateTimeZone from_zone = DateTimeZoneProviders.Tzdb[p_from_zone]; 
    var from_local = LocalDateTime.FromDateTime(p_from_datetime); 
    ZonedDateTime from_datetime = from_zone.AtStrictly(from_local); 

    DateTimeZone to_zone = DateTimeZoneProviders.Tzdb[p_to_zone]; 
    return from_datetime.WithZone(to_zone); 
} 
+2

「インスタント」を実行する必要はありません。 'WithZone'を呼び出してください。 –

+0

@MattJohnsonありがとうございました – fsacer

関連する問題