時刻の扱い方

時刻の基本

Javaの時刻の扱い方はUNIXのそれに似ています。 UNIXではグリニッジ標準時(GMT)の1970年1月1日午前0時(UNIX元年の元旦)からの秒数を int 型で数えています。 グリニッジ標準時は正式には世界時(Universal Time)と呼ばれ,天体の運行を基準に定められているので,進み方が一定ではなく,現在では原子時計に基づく協定世界時(UTC,Coordinated Universal Time)を基準にすることが一般的です。 協定世界時はときどき「うるう秒」(23時59分60秒)が入ります。

UNIXの方式は,秒単位なので粗いだけでなく,21世紀のうちに int 型(32ビット整数)の範囲をはみ出してしまいます。

Javaでは System.currentTimeMillis() というメソッドで現在の協定世界時を得ます。 起点はやはり1970年元旦0時ですが,単位は秒でなくミリ秒(milliseconds)にし,Javaの long 型(64ビット整数)で数えます。 これなら,最大の数は 263 - 1 ですから約 1019 秒まで数えられます。 1日が約 105 秒,1年が約 3×1010 ミリ秒ですから,何億年かは大丈夫でしょう。

現在の時刻を表示させてみましょう。

class Test {
    public static void main(String[] args) {
        long t = System.currentTimeMillis();
        System.out.println("UNIX紀元 " + t + " ミリ秒です。");
    }
}

たとえば「UNIX紀元 1022416607108 ミリ秒です。」のように表示されたでしょうか。

java.util.Date クラス

普通の表し方にするには java.util.Date というクラスを使います。

class Test {
    public static void main(String[] args) {
        System.out.println(new java.util.Date());
    }
}

これを実行すると

Sun May 26 21:37:28 JST 2002

のように出力されます。

このプログラムは次のようにも書けます。

import java.util.*;
class Test {
    public static void main(String[] args) {
        Date d = new Date();
        System.out.println(d);
    }
}

この dDate 型のオブジェクトで,System.out.println() に渡されたため自動的に文字列型に変換されました。 省略しないで書くと

        System.out.println(d.toString());

となります。

java.text.DateFormat クラス

日付のフォーマットには java.text.DateFormat クラスを使うのがよいでしょう。

import java.util.*;
import java.text.*;
class Test {
    public static void main(String[] args) {
        Date date = new Date();
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
                                                       DateFormat.SHORT);
        System.out.println(df.format(date));
    }
}

日付だけでよければ

        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);

時刻だけでよければ

        DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT);

とします。

SHORT のところをいろいろ変えてみましょう。 表示が次のように変わります。

    SHORT   02/05/26 21:49
    MEDIUM  2002/05/26 21:51:34
    LONG    2002/05/26 21:49:58:JST
    FULL    2002年5月26日 21時51分34秒JST

JSTはJapan Standard Time(日本標準時)です。 Java言語ソフト(J2SDK)はアメリカから取ってきたものですが,日本で使っていることを自動認識し,表示も日本語になっていますね。

java.text.SimpleDateFormat クラス

標準的なフォーマットでは嫌だという場合にこのクラスを使います。

import java.util.*;
import java.text.*;
class Test {
    public static void main(String[] args) {
        Date date = new Date();
        DateFormat df =
            new SimpleDateFormat("yyyy-MM-dd (EE) HH:mm:ss.SSS zz");
        System.out.println(df.format(date));
    }
}

実行すると

2002-05-26 (日) 21:54:55.583 JST

のように表示されます。 yyyy が年(yy なら下2桁), MM が月, dd が日, EE が曜, HH が時(0--23), mm が分, ss が秒, SSS がミリ秒, zz がゾーン名(JST,GMTなど)になります。

完全なコントロール

java.util.Calendar クラスを使えば,日付や時・分・秒などを数値として取り出すことができます。
import java.util.*;
class Test {
    static final String[] youbi
        = { " ", "日", "月", "火", "水", "木", "金", "土" };
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance(TimeZone.getDefault());
        cal.setTime(new Date());
        int y = cal.get(Calendar.YEAR);          // 例: 1997
        int m = cal.get(Calendar.MONTH) + 1;     // (0..11) + 1
        int d = cal.get(Calendar.DATE);          // 1..31
        int w = cal.get(Calendar.DAY_OF_WEEK);   // 1=Sun..7=Sat
        int h = cal.get(Calendar.HOUR_OF_DAY);   // 0..23
        int min = cal.get(Calendar.MINUTE);      // 0..59
        int sec = cal.get(Calendar.SECOND);      // 0..59
        int ms = cal.get(Calendar.MILLISECOND);  // 0..999
        System.out.println(y + "年" + m + "月" + d + "日"
                           + youbi[w] + "曜日" + h + "時" + min
                           + "分" + sec + "秒" + ms + "ミリ秒");
    }
}

月だけはUNIXの習慣にしたがって0〜11の範囲になりますので, 1を加えておきます。

実行すると次のように表示されます。

2002年5月26日日曜日21時56分35秒206ミリ秒

ループの中で使うときは,Date のインスタンスを一つ作っておき,次のように setTime() メソッドを使う方が速くなります。

    Date date = new Date();
    Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("JST"));
    for (i = 0; i < N; i++) {
        date.setTime(time[i]);
        cal.setTime(date);
        System.out.println(cal.get(Calendar.SECOND));
    }

奥村晴彦

Last modified: 2005-09-22 15:49:22