TimeUnitクラスで時間計算の可読性を上げる

TimeUnitクラスとは

ある単位の時間を表したり、別の単位へ変換できるクラス。
扱えるのは以下の通り。

ナノ秒  :マイクロ秒の1000分の1
マイクロ秒:ミリ秒の1000分の1
ミリ秒  :秒の1000分の1
分    :60秒
時    :60分
日    :24時間

使用例

3時間のミリ秒を計算する。

Timeunitなし

long millis = 1 * 60 * 60 * 3 * 1000;

※1秒×60で60秒。それが×60で60分。3倍で3時間。1000をかけてミリ秒に変換。

どういう計算か一見して分かりにくい…。
それに計算内容を変更する際、どの値をどう変えるか考える必要がある。

Timeunitあり

long millis = TimeUnit.HOURS.toMillis(3);

コードを見るだけで、3時間をミリ秒に変換していることがわかる。

2.5時間に変更する場合

long millis = TimeUnit.MINUTES.toMillis(150);

150分=2.5時間をミリ秒に変換するよう書き換えればOK。

Timeunitの中身

各時間単位のEnumにより計算されている。
以下は1時間のEnumと定数の中身。

    /**
     * Time unit representing sixty minutes
     */
    HOURS {
        public long toNanos(long d)   { return x(d, C5/C0, MAX/(C5/C0)); }
        public long toMicros(long d)  { return x(d, C5/C1, MAX/(C5/C1)); }
        public long toMillis(long d)  { return x(d, C5/C2, MAX/(C5/C2)); }
        public long toSeconds(long d) { return x(d, C5/C3, MAX/(C5/C3)); }
        public long toMinutes(long d) { return x(d, C5/C4, MAX/(C5/C4)); }
        public long toHours(long d)   { return d; }
        public long toDays(long d)    { return d/(C6/C5); }
        public long convert(long d, TimeUnit u) { return u.toHours(d); }
        int excessNanos(long d, long m) { return 0; }
    },

    // Handy constants for conversion methods
    static final long C0 = 1L;
    static final long C1 = C0 * 1000L;
    static final long C2 = C1 * 1000L;
    static final long C3 = C2 * 1000L;
    static final long C4 = C3 * 60L;
    static final long C5 = C4 * 60L;
    static final long C6 = C5 * 24L;

    /**
     * Scale d by m, checking for overflow.
     * This has a short name to make above code more readable.
     */
    static long x(long d, long m, long over) {
        if (d >  over) return Long.MAX_VALUE;
        if (d < -over) return Long.MIN_VALUE;
        return d * m;

内部的にはオーバーフロー対策の処理も実装されている。

コメントを残す

メールアドレスが公開されることはありません。