やりたいこと
2つの日付から経過年月日(〇年〇ヵ月〇日という具合)を求める。
例
2020/08/01と2020/08/03 → 0年0ヵ月2日
2020/08/01と2020/09/01 → 0年1ヵ月0日
2020/08/01と2021/08/01 → 1年0ヵ月0日
仕様
・From日付 > To日付はエラー(エラーコード:-1)を返す
・日付の書式は yyyy/MM/dd のみ
・From日付、To日付はともにString型
・年、月、日はint[]で返却(0:年、1:月、2:日)
実装
public static int getDateDiff(String paraFromDate, String paraToDate, int[] paraDiffDay) {
int diffYear = 0 ;
int diffMonth = 0 ;
int diffDay = 0 ;
// 起算日の日付を年、月、日に分解(From)
int from_year = parseInt(paraFromDate.substring(0,4)) ;
int from_month = parseInt(paraFromDate.substring(5,7)) ;
int from_day = parseInt(paraFromDate.substring(8,10)) ;
// 基準日の日付を年、月、日に分解(To)
int to_year = parseInt(paraToDate.substring(0,4)) ;
int to_month = parseInt(paraToDate.substring(5,7)) ;
int to_day = parseInt(paraToDate.substring(8,10)) ;
Calendar comp_from = Calendar.getInstance() ;
comp_from.set(from_year, from_month - 1, from_day) ;
Calendar comp_to = Calendar.getInstance() ;
comp_to.set(to_year, to_month - 1, to_day) ;
// 起算日 > 基準日の場合、エラーにする
if(comp_from.compareTo(comp_to) > 0) {
return -1;
}
// 年の差を取得する
diffYear = to_year - from_year ;
// 月を比較
if(from_month > to_month) {
// 起算日の月の方が大きい場合 = 年を跨ぐ
to_month = to_month + 12 ;
// 年をマイナスする
// 同じ年であればfrom_monthの方が大きいことはあり得ないため、マイナスになることはない
diffYear = diffYear - 1 ;
}
// 月の差を取得する
diffMonth = to_month - from_month ;
// 日を比較
// 起算日(From)の方が大きい場合、月を跨いでいると判断
if(from_day > to_day) {
// 起算日の最大日数を加える
to_day = to_day + comp_from.getActualMaximum(comp_from.DATE) ;
// 月の差をマイナスする
diffMonth = diffMonth - 1 ;
}
// 日の差を取得する
diffDay = to_day - from_day ;
// 引数に設定する
paraDiffDay[0] = diffYear ;
paraDiffDay[1] = diffMonth ;
paraDiffDay[2] = diffDay ;
return 0 ;
}
呼び出し側
String fromDate = '2020/08/20' ;
String toDate = '2020/10/01' ;
int diffDate[] = {0,0,0} ;
if( getDateDiff(fromDate, toDate, diffDate) != 0 ) {
// エラー
}
else {
String keikaDate = diffDate[0] + "年" + diffDate[1] + "ヵ月" + diffDate[2] + "日" ;
}
問題点、課題
・エラーハンドリングがない
→ 引数の日付が yyyy/MM/dd の書式でない場合、Exception発生
→ yyyy/MM/dd書式であっても存在しない日付の場合、挙動不正
良かった点
・getActualMaximumを使ってその月の最大日数を取得した
→ 最初は
1,3,5,7,8,10,12月は31日
4、6、9、11月は30日
2月はうるう年なら29日、そうでなければ28日としようとした。
getActualMaximumの一文で解決。