ITエンジニアの技術メモ

神奈川在住のITエンジニアの備忘録です。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

Javaで時刻間の差分を出す

Javaで引数で受け取った2つの時刻間の差分を出すプログラム(calcTimeDiff)を作成した。ログ解析などをしていて、ログ内のある時刻からある時刻までの正確な経過時間が欲しい時、脳内でいちいち計算するのが面倒だったので、これを作成した。

使い方は、
java calcTimeDiff "開始時刻" "終了時刻"
で、"開始時刻" と "終了時刻" との差分を出す。

例えば、
java calcTimeDiff "2019/03/24 22:00:00" "2020/03/24 22:20:30"
として実行すると、結果は、
Diff Time: 366 days 0 hours 20 minutes 30 seconds
となる。

なお、対応している引数の時刻の形式は以下。
yyyy/MM/dd HH:mm:ss (例:2019/03/24 22:00:00)
yyyy/MM/dd HH:mm (例:2019/03/24 22:00)
yyyy/MM/dd HH (例:2019/03/24 22)
yyyy/MM/dd (例:2019/03/24)

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

public class calcTimeDiff {
    public static void main(String[] args) {
        if (args.length != 2) {
            throw new IllegalArgumentException("Both start date and end date are necessary.");
        }
        String startDateStr = args[0];
        String endDateStr   = args[1];
        long timeDiff = getEpochTime(endDateStr) - getEpochTime(startDateStr);

        if (timeDiff < 0) {
            throw new IllegalArgumentException("End date should be later than start date.");
        }
        printTimeDiff(timeDiff);
    }

    private static void printTimeDiff (long timeDiff) {
        int ONE_MIN_MILL_SEC_TIME   = 1000 * 60;
        int ONE_HOUR_MILL_SEC_TIME  = 1000 * 60 * 60;
        long ONE_DAY_MILL_SEC_TIME  = 1000 * 60 * 60 * 24;

        long days = timeDiff / (ONE_DAY_MILL_SEC_TIME);
        int restExceptDays = (int)(timeDiff % (ONE_DAY_MILL_SEC_TIME));
        int hours = restExceptDays / ONE_HOUR_MILL_SEC_TIME;
        int restExceptHours = restExceptDays % (ONE_HOUR_MILL_SEC_TIME);
        int mins = restExceptHours / ONE_MIN_MILL_SEC_TIME;
        int restExceptMins = restExceptHours % (ONE_MIN_MILL_SEC_TIME);
        int seconds = restExceptMins / 1000;

        System.out.printf("Diff Time: %d days %d hours %d minutes %d seconds", days, hours, mins, seconds);
    }

    private static long getEpochTime (String dateStr) {
        List<SimpleDateFormat> formatters = new ArrayList<SimpleDateFormat>();
        formatters.add(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
        formatters.add(new SimpleDateFormat("yyyy/MM/dd HH:mm"));
        formatters.add(new SimpleDateFormat("yyyy/MM/dd HH"));
        formatters.add(new SimpleDateFormat("yyyy/MM/dd"));

        long epochTime = 0;
        int counter = 0;
        for (SimpleDateFormat formatter : formatters) {
            try {
                epochTime = formatter.parse(dateStr).getTime();
                break;
            }
            catch (ParseException ex) {
                counter++;
                if (counter >= formatters.size()) {
                    throw new IllegalArgumentException("Failed to format the input date", ex);
                }
            }
        }
        return epochTime;
    }
}