Javaで 日付の差 差分日数を取得する際に間違えたこと
日付関連のユーティリティクラスとして DateUtilsクラスを作っている時に書いたメモです。
まず初めにソースを貼ります。
import java.util.Calendar; import java.util.Date; public class Test { public static void main(String args[]){ Calendar cal1 = Calendar.getInstance(); cal1.set(2014, 0, 1); Date dateFrom = cal1.getTime(); Calendar cal2 = Calendar.getInstance(); cal2.set(2014, 0, 2); Date dateTo = cal2.getTime(); int result = diffDays(dateFrom, dateTo); System.out.println(result); } /** * 日付の差分日数を取得. * * 参考: http://javatechnology.net/java/date-diff-days/ * : http://sattontanabe.blog86.fc2.com/blog-entry-88.html * @param dateFrom 開始日付 * @param dateTo 終了日付 * @return int 差分日数 */ public static int diffDays(Date dateFrom, Date dateTo){ // 日付をlong値に変換 long dateTimeFrom = dateFrom.getTime(); long dateTimeTo = dateTo.getTime(); // 差分の日数を計算 final int DAY_MILLISECONDS = (1000 * 60 * 60 * 24 ); int diff = (int)( dateTimeTo - dateTimeFrom ); int dayDiff = diff / DAY_MILLISECONDS; return dayDiff; } }
ソースを見ていただけるとわかると思うのですが
2014年1月1日と2014年1月2日の差分日数を求めています。
ですが、差分日数が30日になるよう下記に変更してテストしたところ・・・。
Calendar cal2 = Calendar.getInstance(); cal2.set(2014, 0, 31);
なぜマイナス!!!
いろいろ調べたところ原因は
int diff = (int)( dateTimeTo - dateTimeFrom );
この部分でした。
Date型から.getTime()して取得できる値は
1970年1月1日午前0時(GMT)から現在までの経過秒数なので
2014年1月1日の場合は : 138,854,114,035秒になります。
ここで自分が忘れていたことは int型の最大値・・・。
参考 : Java の Short, Integer, Long, Float, Double 型の最大値 / 最小値 & それぞれの値を漢数字表記すると - #侍ズム
int型の最大値は : 2,147,483,647
1日の秒数は 86,400,000。これはプログラム中にfinal int DAY_MILLISECONDSとして定義しています。
ということは、int型が扱える日数は
2,147,483,647 / 86,400,000 = 24.85513..... = 24日
原因だった (int)(dateTimeTo - dateTimeFrom)は
差分日数を秒数で計算しているので
1日~24日までは計算できるが 25日以上になるとオーバーフローしてしまいエラーになってしまう。
理由が分かったので、解決方法を書くと
型を int⇒longに変更するだけでOK。
int型の最大値: 2,147,483,647
long型の最大値: 9,223,372,036,854,775,807
なのでlong型だと安心出来ますね。
long型で許容できる日数を計算すると
約292471208年分ほど格納できるみたいです。