Javaで日付・時刻を扱う場合、大雑把に以下の3つのクラスを組み合わせて使います。

  • 日付・時刻を扱うクラス「java.util.Date」
  • カレンダークラス「java.util.Calendar」
  • 文字列との変換クラス「java.text.SimpleDateFormat」

■目次


システム時刻を取得

// システム時刻を取得(現在時刻が 2013/11/22 01:01:51.929 の場合)
Date date = new Date();
// システム時刻を出力してみる
System.out.println(date.getTime());
   // 結果 -> 1385049711929
System.out.println(date);
   // 結果 -> Fri Nov 22 01:01:51 JST 2013
 Javaでシステム時刻(PCに設定されている時刻)を取得するには、Dateクラスを新しく作るだけでOKです。ただし、Dateクラスは日時を内部でlongの整数で扱うため、そのままでは人間には理解できず、Dateクラスをそのまま文字列に変換すると、日本人にはあまり馴染みのない形式で出力されます。

システム時刻を文字列に変換

// システム日付を取得
Date date = new Date();
// 変換クラスを作成
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS");
// Date型から文字列に変換
String str = sdf.format(date);
System.out.println(str);
   // 結果 -> 2013/11/22 01:01:51.929
 Dateクラスを日本人に馴染みのある形式の文字列にするには、SimpleDateFormatクラスのformat関数を使います。SimpleDateFormatクラスを作成する際のパラメータに、上記のようなパラメータを渡すことで変換する書式を指定できます。書式のパラメータに「yyyyMMdd」なら「20131122」に変換されます。
 テキストファイルや画面に時刻を表示する際にも文字列への変換は必要になります。

文字列から時刻(Date型)に変換

// 日付文字列(yyyy/MM/dd形式)
String str = "2013/11/22";
// 変換クラスを作成
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
// 文字列からDate型に変換
Date date = sdf.parse(str);
// 変換結果を出力してみる
System.out.println(date.getTime());
   // 結果 -> 1385046000000
System.out.println(date);
   // 結果 -> Fri Nov 22 00:00:00 JST 2013
 文字列からDate型に変換するには、SimpleDateFormatクラスのparse関数を使います。日時の比較や、3日後や1ヶ月後を求めるには文字列のままではやりにくいので変換も必要になります。

カレンダークラスを取得 + カレンダークラスの内容を出力

// カレンダークラスを取得
Calendar cal = Calendar.getInstance();
// カレンダークラスの内容を出力してみよう(現在時刻が 2013/11/22 01:01:51.929 の場合)
// 年 結果 -> 2013
System.out.println(cal.get(Calendar.YEAR));
// 月 結果 -> 10
System.out.println(cal.get(Calendar.MONTH));
// 日 結果 -> 22
System.out.println(cal.get(Calendar.DAY_OF_MONTH));
// 時 結果 -> 1
System.out.println(cal.get(Calendar.HOUR_OF_DAY));
// 分 結果 -> 1
System.out.println(cal.get(Calendar.MINUTE));
// 秒 結果 -> 51
System.out.println(cal.get(Calendar.SECOND));
// ミリ秒 結果 -> 929
System.out.println(cal.get(Calendar.MILLISECOND));
 カレンダークラスはDate型と違って「new Calendar()」とはしません。「Calendar.getInstance()」でカレンダークラスを作成します。Date型と同じように、作成した時点でシステム時刻が設定されています。
 カレンダークラスは年・月・日・時・分・秒・ミリ秒などを上記のように「cal.get(Calendar.YEAR)」とすることで個別に取得できるのが特徴です。この時注意が必要なのが「月」で、月はなぜか1月なら 0、2月なら 1、のように実際の月より1少ない数字が取得できます。

カレンダークラスで日付の計算

// 3年後の計算
cal.add(Calendar.YEAR, 3);
// 3年前の計算
cal.add(Calendar.YEAR, -3);
// 3ヶ月後の計算
cal.add(Calendar.MONTH, 3);
// 3ヶ月前の計算
cal.add(Calendar.MONTH, -3);
// 3日後の計算
cal.add(Calendar.DAY_OF_MONTH, 3);
// 3日前の計算
cal.add(Calendar.DAY_OF_MONTH, -3);
// 3時間後の計算
cal.add(Calendar.HOUR_OF_DAY, 3);
// 3時間前の計算
cal.add(Calendar.HOUR_OF_DAY, -3);
// 3分後の計算
cal.add(Calendar.MINUTE, 3);
// 3分前の計算
cal.add(Calendar.MINUTE, -3);
// 3秒後の計算
cal.add(Calendar.SECOND, 3);
// 3秒前の計算
cal.add(Calendar.SECOND, -3);
 カレンダークラスのもう一つの特徴は、3日後や3日前といった日付の計算が簡単にできることです。add関数に 3 を入れれば3日後や3ヶ月後、-3なら3日前や3ヶ月前の計算ができます。

カレンダークラスとDate型の変換

// カレンダークラスからDate型に変換
Date date = cal.getTime();
// Date型の値をカレンダークラスに設定
cal.setTime(date);
 カレンダークラスとDate型のやりとりは、getTime、setTime関数を使うだけでとても簡単に行えます。

文字列の日付の3ヶ月後を計算して文字列の日付に戻すサンプル

import java.text.*;
import java.util.*;

public class DateTimeSample {
 public static void main(String[] args) throws ParseException {
   // 文字列の日付
   String str = "2013/11/22";
   // フォーマッタを作成
   SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
   // 文字列の日付からDate型に変換
   Date date = sdf.parse(str);
   // カレンダークラス作成
   Calendar cal = Calendar.getInstance();
   // カレンダークラスにDateの値を設定
   cal.setTime(date);
   // 3ヶ月後を計算
   cal.add(Calendar.MONTH, 3);
   // カレンダークラスからDate型を取得
   date = cal.getTime();
   // Date型から文字列の日付に変換
   String str2 = sdf.format(date);
   // 変換結果を出力 結果 -> 2014/02/22
   System.out.println(str2);
 }
}
 これまでに挙げてきた、文字列からDate型への変換、カレンダークラスにDate型の値を設定、日付の計算、カレンダークラスからDate型を取得、Date型から文字列への変換を組み合わせるとこんな事も可能です。

日付の比較(Date型同士) ideone

after関数

// date1が、date2より後の日時であれば true
if (date1.after(date2))
  System.out.println("date1はdate2より後の日時です");
else
  System.out.println("date1はdate2と同じか前の日時です");

before関数

// date1が、date2より前の日時であれば true
if (date1.before(date2))
  System.out.println("date1はdate2より前の日時です");
else
  System.out.println("date1はdate2と同じか後の日時です");
 after関数とbefore関数です、after関数は、基となるDateがパラメータのDateよりも後(after)であれば true が返ります。before関数はその逆です。管理人はあまり使いません。

compareTo関数

// date1 = date2なら0
if (date1.compareTo(date2) == 0)
  System.out.println("date1とdate2は同じ日時です");
// date1 < date2ならマイナスの値
if (date1.compareTo(date2) < 0)
  System.out.println("date1はdate2より前の日時です");
// date1 > date2ならプラスの値が返却されます
if (date1.compareTo(date2) > 0)
  System.out.println("date1はdate2より後の日時です");
 compareTo関数は、同じなら 0、date1 < date2 ならマイナスの値、date1 > date2 ならプラスの値が返ってきます。compareTo関数一つで同じか、過去か未来かを判断できる便利な関数ですが、管理人は過去と未来がどっちがどっちか分からなくなるのであまり使いません。

Date型が内部で扱うlong値を使った比較

if (date1.getTime() == date2.getTime())
  System.out.println("date1とdate2は同じ日時です");
if (date1.getTime() > date2.getTime())
  System.out.println("date1はdate2より後の日時です");
if (date1.getTime() < date2.getTime())
  System.out.println("date1はdate2より前の日時です");
 Date型は内部でlongを使って時刻を保持します。getTime関数でそのlong値を取得できるので、これを比較演算子(== > < != など)で比較する方法です。管理人はこの方法が見た目で過去未来をどのように判定しようとしているか分かりやすいのでよく使います。

文字列の日付が実際に存在する日付か確認する

String str1 = "2013/11/31"; // 存在しない日付
// 変換クラスを作成
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
// 文字列をDate型に変換
Date date = sdf.parse(str1);
// Date型から文字列に再変換
String str2 = sdf.format(date); // 再変換結果 2013/12/01
// 再変換した文字列と元の文字列で比較
if (str2.equals(str2))
  System.out.println(str2 + "は、存在する日付です。");
else
  System.out.println(str2 + "は、存在しない日付です。");
 SimpleDateFormatで存在しない日時を変換すると、実在する日時を越えた分だけ進めたDate型に変換されます。このDate型を文字列に戻すと、例えば「2013/11/31」は「2013/12/01」に変換されるので、変換前と返還後の文字列を比較して、同じであれば存在する日付、同じでなければ存在しない日付と判断できます。
最終更新:2013年11月24日 06:37