私の他の答えは、質問で提起された直接の問題を正しく解決します。この答えはおまけであり、経過時間を計算して適用するという目標を達成するための代替手段です。
これらのライブラリのいずれかを使用すると、この種の日時処理を行うのがはるかに簡単になります。
Java にバンドルされている古い日時クラス (java.util.Date、.Calendar、java.text.SimpleDateFormat) は、厄介で混乱し、欠陥があることで有名です。それらを避けてください。必要に応じて、上記のいずれかのライブラリと相互に変換できます。
Joda-Time
以下のコード例は、Joda-Time 2.5 を使用しています。
経過時間
経過時間は、次の 2 つの方法のいずれかでカウントできます。
- カレンダースタイル
月、週、日などの数。
- ストップウォッチスタイル実行中のストップウォッチ
で測定されたかのように、ミリ秒の合計数。
経過時間を測定するこれら 2 つの方法は、異なる結果をもたらす可能性があります。このコード例は両方を示しています。
タイムゾーン
juDate とは異なり、Joda DateTime
-Time のオブジェクトは、実際に割り当てられた独自のタイム ゾーンを認識しています。経過時間をカレンダー スタイル (月、日など) でカウントする場合、これは非常に重要です。この例では、ケベック州モントリオールのタイム ゾーン (任意に選択) を使用していることに注意してください。
サンプルコード
// Simulate inputs, a trio of java.util.Date objects.
java.util.Date dateStart = new DateTime( 2014 , 1 , 2 , 0 , 0 , 0 , DateTimeZone.UTC ).toDate();
java.util.Date dateStop = new DateTime( 2014 , 3 , 2 , 0 , 0 , 0 , DateTimeZone.UTC ).toDate();
java.util.Date dateTarget = new DateTime( 2014 , 7 , 1 , 0 , 0 , 0 , DateTimeZone.UTC ).toDate();
// Convert inputs to Joda-Time
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" ); // Or DateTimeZone.UTC.
DateTime start = new DateTime( dateStart , timeZone );
DateTime stop = new DateTime( dateStop , timeZone );
DateTime target = new DateTime( dateTarget , timeZone );
// Determine elapsed time in three fashions: (a) pair of points on timeline, (b) An amount of weeks, days, hours, and such, and (c) actual milliseconds.
Interval interval = new Interval( start , stop );
Period period = interval.toPeriod();
Duration duration = interval.toDuration();
// Add elapsed time to target date-time. Show results of adding either period or duration.
DateTime laterByPeriod = target.plus( period );
DateTime laterByDuration = target.plus( duration );
コンソールにダンプします。
System.out.println( "dateStart: " + dateStart ); // BEWARE: j.u.Date objects are in UTC by definition, but "toString" method applies the JVM's current default time zone. Misleading!
System.out.println( "dateStop: " + dateStop );
System.out.println( "dateTarget: " + dateTarget );
System.out.println( "start: " + start );
System.out.println( "stop: " + stop );
System.out.println( "target: " + target );
System.out.println( "interval: " + interval );
System.out.println( "period: " + period );
System.out.println( "duration: " + duration );
System.out.println( "laterByPeriod: " + laterByPeriod ); // Notice the change in offset because of DST (Daylight Saving Time) in Québec.
System.out.println( "laterByDuration: " + laterByDuration );
走るとき。
dateStart: Wed Jan 01 16:00:00 PST 2014
dateStop: Sat Mar 01 16:00:00 PST 2014
dateTarget: Mon Jun 30 17:00:00 PDT 2014
start: 2014-01-01T19:00:00.000-05:00
stop: 2014-03-01T19:00:00.000-05:00
target: 2014-06-30T20:00:00.000-04:00
interval: 2014-01-01T19:00:00.000-05:00/2014-03-01T19:00:00.000-05:00
period: P2M
duration: PT5097600S
laterByPeriod: 2014-08-30T20:00:00.000-04:00
laterByDuration: 2014-08-28T20:00:00.000-04:00