4

Joda-Time を使用して、2 つの時点の間の期間を知るために使用しようとしています。各時点は独自のローカル タイムゾーンで指定されます。

例:

DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
DateTime utc1 = ny.withZone(DateTimeZone.UTC);
DateTime utc2 = la.withZone(DateTimeZone.UTC);        
Period period = new Period(utc1, utc2);

さて、これが夏時間とうるう年を考慮しているかどうかを知りたいのですが...また、「期間」の使用はこれを達成するための正しいJoda-Timeの方法ですか? ありがとう ;)

4

2 に答える 2

10

あなたが提供したコードは機能し、タイムゾーンを考慮しますが、UTC への変換を行う必要はありません。このコードはより単純で、同じことを行います (Period ではなく Duration を使用):

DateTime ny = new DateTime(2011, 2, 2, 7, 0, 0, 0, DateTimeZone.forID("America/New_York"));
DateTime la = new DateTime(2011, 2, 3, 10, 15, 0, 0, DateTimeZone.forID("America/Los_Angeles"));
Duration duration = new Interval(ny, la).toDuration();
于 2011-02-13T12:22:30.483 に答える
4

使い方によっては、上記のコードは適切ではない場合があります。

年/月/日/時などの int を取るすべての DateTime コンストラクターは、夏時間 (DST) 移行期間に対して脆弱です。この場合、Joda-time は例外をスローします。したがって、遷移中の時間をアプリケーションで入力できる場合、失敗します。

DateTime ny = new DateTime(2011, 3, 13, 2, 0, 0, 0, DateTimeZone.forID("America/New_York"));

Exception in thread "main" java.lang.IllegalArgumentException: Illegal instant due to time zone offset transition: 2011-03-13T07:00:00.000
at org.joda.time.chrono.ZonedChronology.localToUTC(ZonedChronology.java:143)
at org.joda.time.chrono.ZonedChronology.getDateTimeMillis(ZonedChronology.java:119)
at org.joda.time.chrono.AssembledChronology.getDateTimeMillis(AssembledChronology.java:133)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:254)
at org.joda.time.base.BaseDateTime.<init>(BaseDateTime.java:223)
at org.joda.time.DateTime.<init>(DateTime.java:264)

同様に、指定されたタイムゾーンには 2 * 2 時があるため、どの時間が参照されているかを判断できない場合、秋に別の問題に直面することになります。DateTime メソッド withHourOfday および withTime は、同じ問題に対して脆弱であり、DST の影響を受けるタイムゾーンを含む文字列として日時を解析します。

考えられる回避策は次のとおりです。

  • 代わりに任意の固定オフセット タイムゾーン (UTC など) でインスタンス化する
  • UTC タイムゾーンの文字列と同じように解析する
  • ローカル タイム ゾーン (真夜中など) で有効な時間をインスタンス化し、plusHours を使用して目的の時間まで進める
  • 遷移日の 2 時間目から保護するためのガード (if ステートメント) がある
  • 例外をキャッチし、(DateTimeZone.nextTransition を使用して) 次の遷移がいつ発生するかを確認し、それに応じて前後に移動します
于 2011-04-01T19:55:36.610 に答える