2011-06-22 22 views
9
Date nowdate = new Date(); 
long nowms = nowdate.getTime(); 
long differencems = numdaysback * 24 * 60 * 60 * 1000; 
long thenms = nowms - differencems; 
Date thendate = new Date(thenms); 

numdaysbackが365の場合、thendateは1年前と思われます。しかし、それは...約3週間前ですか?Java日付問題、日付を見つけるのはX日前

についてどのように
NUMDAYSBACK: 365 
NOWDATE: Wed Jun 22 20:31:58 SGT 2011 
NOWMS: 1308745918625 
DIFFERENCEMS: 1471228928 
THENMS: 1307274689697 
THENDATE: Sun Jun 05 19:51:29 SGT 2011 

答えて

25

Calendar cal = Calendar.getInstance(); 
cal.add(Calendar.YEAR, -1); 
Date thendate = cal.getTime(); 

は関係なく、DSTの日の同じ時刻を返しますか、閏年、短くかつ明確である...

一般Calendarは、そのような中で移動するための方法でありますJoda Timeのようなサードパーティのライブラリを使用している場合を除きます。 N日/時間/月/秒を追加し、時間を1時間に切り捨てるなど、あらゆる種類の計算に使用できます。longであまりにも痛みを伴うもの。

元の質問に関しては、整数オーバーフローの犠牲者のようです。乗算は、明示的に長く使用している場合、それは動作します:

long differencems = 365 * 24 * 60 * 60 * 1000L; 
+0

良い解決策。今ではそれが意図したとおりに動作しています。 – Jesper

+3

+1何が間違っているのかは、単純に解決策を提示するのではなく、彼に伝えます。 –

0

このライン:

long differencems = numdaysback * 24 * 60 * 60 * 1000; 

RHSは次のようになります。31536000000.あなたがはるかに少ないものを持って、RHSている理由は、intとして評価されています(すべての数量が整数なので)、MAX_INTを超えています。これを修正するには

1000を長くする "l"に注意してください。これでRHSは長く評価されます。

+0

ここにいる皆様に感謝します。私はカレンダーに行くことをお勧めします。 – Jesper

3

ちょうどこの試してください:あなたは、乗算を整数に起因する数字を失うことはありません新しいコードで

long differencems = numdaysback * 24L * 60 * 60 * 1000; 

を。 リテラル24には長さが設定されているので、最初のオペランドnumdaysbackをlongに自動変換することで乗算が行われます。残りの乗算はロングオペランドでも行われます。

0

Dateクラスは(非公式に)非推奨です。 APIには非常に多くのフォルトがあるため、Dates/Timesを正しく取得することは実際には困難です。最も簡単な例は、differencemsのコードのようなものです。その間に夏時間スイッチ(UTを使用しない場合)が含まれていて、常にうるう秒を処理できない場合は失敗します。

アプリケーションが正しい日付に依存している場合は、Joda Timeを使用します。

関連する問題