プログラムで扱う事ができるデータ型のうち、日付型のデータを扱う機会は非常に多い。
それはJavaプログラミングにおいても例外ではないが、Javaの場合は日付を扱えるクラスが複数あるので混乱する方も多いだろう。
このページでは、Javaにおける日付の扱い方について、基本的な使い方とクラスごとの詳細について紹介していく。
目次
Javaで今日の日付を取得する
細かいことはいいから、とりあえず今日の日付の出し方を知りたい、という方もいると思う。はじめにJavaで今日の日時を取得する方法だけお伝えしておく。
Javaで現在の日時を取得する方法は次の通りだ。
Dateクラスを使う
1 2 3 4 5 6 7 8 9 |
import java.util.Date; public class Main { public static void main(String[] args) { Date date = new Date(); System.out.println(date.toString()); } } |
Calenderクラスを使う
1 2 3 4 5 6 7 8 9 |
import java.util.Calendar; public class Main { public static void main(String[] args) { Calendar calendar = Calendar.getInstance(); System.out.println(calendar.getTime().toString()); } } |
それぞれのクラスの詳細は、下に載っているので確認してほしい。
日付に関連するクラスの種類
Javaプログラミングにおいて、日付型を扱うときに使用する代表的なクラスは以下の通りだ。
クラス |
内容 |
java.util.Date |
日付を扱うクラス |
java.util.Calendar |
日付の操作、計算などを扱うクラス |
java.text.SimpleDateFormat |
日付書式を扱うクラス |
日付を扱うクラスとしては、JDK1.8から新しくjava.timeパッケージがリリースされているが、まずは基本となる上記の3つのクラスについて理解しておこう。java.timeパッケージは別の機会にでも紹介する。
Dateクラス(java.util.Date)
Dateクラスはjavaの初期から使われているクラスで、単純に日付を取得したいときや簡単に表示したい時などに使うケースが多い。
主なメソッド
戻り値の型 |
メソッド |
内容 |
boolean |
after(Date dt) |
2つのDateを比較し、指定した日付より後の日付かどうかを判定する。 |
boolean |
before(Date dt) |
2つのDateを比較し、指定した日付より前の日付かどうかを判定する。 |
Object |
clone() |
Dateオブジェクトのコピーを返す。 |
int |
compareTo(Date dt) |
2つのDate型を比較する。同じ場合は0、引数の日付が前の日付の場合は正の値、引数の日付が後の日付の場合は負の値を返す。 |
boolean |
equals(Object obj) |
2つのDateが等しいかどうかを判定する。 |
String |
toString() |
Dateを文字列で返す。 |
サンプルプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import java.util.Date; public class Main { public static void main(String args[]){ //Dateオブジェクトを生成する Date dt = new Date(); //[1] //Dateのコピーを生成する Date dt2 = (Date) dt.clone(); //[2] //Dateの設定内容を出力 System.out.println("[3] dtを表示 : " + dt.toString()); System.out.println("[4] dt2を表示 : " + dt2.toString()); //指定された日付の前後を比較 boolean ret; ret = dt2.after(dt); System.out.println("[5] dt2はdtより後の日時かどうか : " + ret); ret = dt2.before(dt); System.out.println("[6] dt2はdtより前の日時かどうか : " + ret); ret = dt2.equals(dt); System.out.println("[7] dt2はdtと同じ日時かどうか : " + ret); //日付の比較 int i = dt.compareTo(dt2); System.out.println("[8] dtとdt2の比較 : " + i); } } |
実行結果
1 2 3 4 5 6 |
[3] dtを表示 : Thu Jun 16 15:46:14 JST 2016 [4] dt2を表示 : Thu Jun 16 15:46:14 JST 2016 [5] dt2はdtより後の日時かどうか : false [6] dt2はdtより前の日時かどうか : false [7] dt2はdtと同じ日時かどうか : true [8] dtとdt2の比較 : 0 |
プログラムの説明
それでは簡単に説明してみよう。[]で囲んだ番号はサンプルプログラムの位置を意味するので、プログラムや実行結果を見る時に役立ててほしい。
- [1]Dateオブジェクトを新しく生成している。この時点では生成した日付が設定される。
- [2]新しいDateオブジェクトをコピーしている。
- [3]dtを文字列で表示している。Dateオブジェクトは海外のフォーマットで表示されるので、日本人にはなじみにくいかもしれない。
- [4]dtをコピーしたdt2を表示している。コピーしているので値は同じとなる。
- [5]dtとdt2をafter()で比較している。同じ値なので「false」が返る。
- [6]dtとdt2をbefore()で比較している。同じ値なので「false」が返る。
- [7]dtとdt2をequals()で比較している。同じ値なので「true」が返る。
- [8]dtとdt2の日付の差を比較している。同じ値なので「0」となる。
Dateクラスで注意すること
このクラスを注意しておきたいのは、非推奨のメソッドが多いという点だ。
非推奨のメソッドというのは、Dateオブジェクトが生まれた当時は使われていたが、javaの改変につれて使われなくなり、別クラスのメソッドに置き換わった機能のことを意味している。今でも非推奨のメソッドを使う事ができるが、非推奨のメソッドを使うことはあまりオススメしない。今後、javaの改変が進むにつれて、非推奨のメソッドが使えなくなる可能性もあるからだ。
サンプルでは同じ日付のDateオブジェクトばかり比較しているのがわかる。本来なら別の日付を比較したいところだが、Dateクラスで日付を操作するメソッドは非推奨なのであえて使用していない。非推奨のメソッドはDateだけでなく他にもあるので、新しいクラスを操作する場合はjavadocを見てチェックするようにしてほしい。
Calendarクラス(java.util.Calendar)
CalendarクラスはDateクラスよりも豊富な機能を持っており、文字通りカレンダーを見るように日付の計算や参照ができるクラスだ。
主なメソッド
戻り値の型 |
メソッド |
内容 |
Calendar |
getInstance() |
カレンダーオブジェクトを取得する。 |
int |
get(int fld) |
指定したカレンダーフィールド(年、月、日など)の値を返す。 |
void |
set(int fld, int val) |
指定したカレンダフィールドに値を設定する。 |
void |
set(int year, int month, int day) |
年、月、日を設定する。 |
boolean |
equals(Object obj) |
2つのCalendarが等しいかどうかを判定する。 |
void |
add(int fld, int val) |
指定したカレンダーフィールドに値を加算・減算する。 |
boolean |
after(Object obj) |
2つのCalendarを比較し、指定した日付より後の日付かどうかを判定する。 |
boolean |
before(Object obj) |
2つのCalendarを比較し、指定した日付より前の日付かどうかを判定する。 |
void |
clear() |
Calendarオブジェクトをクリアする。 |
void |
setLenient(boolean lenient) |
日付の解釈を厳密に行うかどうかを設定する。 |
サンプルプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
import java.util.Calendar; public class Main { public static void main(String args[]){ Calendar cal = Calendar.getInstance(); //[1] //主なCalendarメソッド //各種形式の取得 System.out.println("[2] 年を表示 : " + cal.get(Calendar.YEAR)); System.out.println("[3] 月を表示 : " + cal.get(Calendar.MONTH)); System.out.println("[4] 日付を表示 : " + cal.get(Calendar.DATE)); System.out.println("[5] 紀元前後を表示 : " + cal.get(Calendar.ERA)); System.out.println("[6] 現在の年の何日目かを表示 : " + cal.get(Calendar.DAY_OF_YEAR)); System.out.println("[7] 現在の月の何日目かを表示 : " + cal.get(Calendar.DAY_OF_MONTH)); System.out.println("[8] 曜日を表示 : " + cal.get(Calendar.DAY_OF_WEEK)); System.out.println("[9] 現在の月の何度目の曜日かを表示 : " + cal.get(Calendar.DAY_OF_WEEK_IN_MONTH)); System.out.println("[10] 現在の年の何週目かを表示 : " + cal.get(Calendar.WEEK_OF_YEAR)); System.out.println("[11] 現在の月の何週目かを表示 : " + cal.get(Calendar.WEEK_OF_MONTH)); System.out.println("[12] 年を表示(定数を使わない) : " + cal.get(1)); //カレンダーの設定 cal.set(Calendar.YEAR, 2017); System.out.println("[13] setで変更した日付を表示(年だけ指定) : " + getCalString(cal)); cal.set(2016, 1, 1); System.out.println("[14] setで変更した日付を表示(年月日指定) : " + getCalString(cal)); Calendar cal2 = Calendar.getInstance(); System.out.println("[15] 新しいカレンダーオブジェクトを生成 : " + getCalString(cal2)); //カレンダーの比較 boolean ret; ret = cal.equals(cal2); System.out.println("[16] calとcal2が同じかどうか : " + String.valueOf(ret)); ret = cal.after(cal2); System.out.println("[17] calがcal2より後の日付かどうか : " + String.valueOf(ret)); ret = cal.before(cal2); System.out.println("[18] calがcal2より前の日付かどうか : " + String.valueOf(ret)); cal.add(Calendar.MONTH, 1); System.out.println("[19] calにひと月加算 : " + getCalString(cal)); //厳密な解釈を行い、ありえない日(2016年2月32日)を設定 cal.setLenient(true); cal.set(2016,1,32); System.out.println("[20] 厳密な解釈をして、ありえない日を設定 : " + getCalString(cal)); //厳密な解釈を行わずに、ありえない日(2016年2月32日)を設定 cal.setLenient(false); cal.set(2016,1,32); try{ System.out.println("[21] 厳密な解釈をせずに、ありえない日を設定 : " + getCalString(cal)); }catch(Exception ex){ System.out.println("[21] 厳密な解釈をせずに、ありえない日を設定 するとエラーになる"); } //値のクリア cal.clear(); System.out.println("[22] 値をクリアする : " + getCalString(cal)); } //カレンダーを年月日の文字列で取得 private static String getCalString(Calendar tmpCal){ return String.valueOf(tmpCal.get(Calendar.YEAR)) + "/" + String.valueOf(tmpCal.get(Calendar.MONTH)) + "/" + String.valueOf(tmpCal.get(Calendar.DATE)); } } |
実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[2] 年を表示 : 2016 [3] 月を表示 : 5 [4] 日付を表示 : 16 [5] 紀元前後を表示 : 1 [6] 現在の年の何日目かを表示 : 168 [7] 現在の月の何日目かを表示 : 16 [8] 曜日を表示 : 5 [9] 現在の月の何度目の曜日かを表示 : 3 [10] 現在の年の何週目かを表示 : 25 [11] 現在の月の何週目かを表示 : 3 [12] 年を表示(定数を使わない) : 2016 [13] setで変更した日付を表示(年だけ指定) : 2017/5/16 [14] setで変更した日付を表示(年月日指定) : 2016/1/1 [15] 新しいカレンダーオブジェクトを生成 : 2016/5/16 [16] calとcal2が同じかどうか : false [17] calがcal2より後の日付かどうか : false [18] calがcal2より前の日付かどうか : true [19] calにひと月加算 : 2016/2/1 [20] 厳密な解釈をして、ありえない日を設定 : 2016/2/3 [21] 厳密な解釈をせずに、ありえない日を設定 するとエラーになる [22] 値をクリアする : 1970/0/1 |
プログラムの説明
それではサンプルプログラムを簡単に説明してみよう。
- [1]カレンダーオブジェクトを生成する。生成するにはgetInstance()を使用する。
- [2]カレンダーの「年」を表示する。
- [3]カレンダーの「月」を表示する。月はは定数で表される。
- [4]カレンダーの「日」を表示する。
- [5]紀元前、紀元後を表示する。紀元前の場合は0、紀元後の場合は1が表示される。
- [6]日付がその年の最初から何日目かを表示する。
- [7]日付がその月の最初から何日目かを表示する。
- [8]曜日を表示する。曜日は定数で表される。
- [9]その月の何度目の曜日かを表示する。
- [10]日付がその年の最初の週から何週目かを表示する。
- [11]日付がその月の最初の週から何週目かを表示する。
- [12]年を表示する。YEARなどの定数を使わなくても、数値が分かれば同じ結果となる。
- [13]set()メソッドでは特定のカレンダーフィールドだけ指定して値の設定ができる。
- [14]年月日全てを指定して値の設定も可能だ。
- [15]別のカレンダーオブジェクトを生成。
- [16]calとcal2をequals()で比較している。異なる値なので「false」が返る。
- [17]calとcal2をafter()で比較している。cal2の方が後の日付なので「false」が返る。
- [18]calとcal2をbefore()で比較している。cal2の方が後の日付なので「true」が返る。
- [19]add()メソッドを使って年を加算する。
- [20]厳密な解釈をする設定をして、ありえない日を設定する。この場合は2016/1/32を設定しており、2月の最大日数である29日より3日余分だが、余分となった日付も正しく加算してくれている。
- [21]厳密な解釈をしない設定の場合、ありえない日を設定した場合はエラーとなる。try~catchでエラートラップをしているが、この場合はエラーが発生したのでcatch句の文字を出力している。
- [22]カレンダーをクリアする。クリアするとデフォルトの日付が設定される。
Calendarクラスの定数について
Calendarクラスでは定数を指定してのメソッド実行や、実行結果の戻り値が定数となるケースがある。定数とは意味がある文字列で数値などの値を示したものだ。0や1だと何を意味するのかがわかりにくいが、YEARやMONTHだと「年」「月」というように、プログラマーが内容を理解しやすいように定められている。
このプログラムの例では、get()メソッドで使用するCalendar定数、[3]のステップの月、[8]のステップの曜日などが定数となっているが、これらの定数は以下のとおりだ。
Calendar定数
定数 |
値 |
ERA |
0 |
YEAR |
1 |
MONTH |
2 |
WEEK_OF_YEAR |
3 |
WEEK_OF_MONTH |
4 |
DATE |
5 |
DAY_OF_MONTH |
5 |
DAY_OF_YEAR |
6 |
DAY_OF_WEEK |
7 |
月の定数
定数 |
値 |
JANUARY |
0 |
FEBRUARY |
1 |
MARCH |
2 |
APRIL |
3 |
MAY |
4 |
JUNE |
5 |
JULY |
6 |
AUGUST |
7 |
SEPTEMBER |
8 |
OCTOBER |
9 |
NOVEMBER |
10 |
DECEMBER |
11 |
UNDECIMBER |
12 |
曜日定数
定数 |
値 |
SUNDAY |
1 |
MONDAY |
2 |
TUESDAY |
3 |
WEDNESDAY |
4 |
THURSDAY |
5 |
FRIDAY |
6 |
SATURDAY |
7 |
定数は直接値を指定することもできる。サンプルプログラムの[12]では値を直接指定しているが、読みづらいソースになるので定数を使う様にしたほうがいい。また、これらの定数のうち、月の定数については注意が必要だ。Calendarオブジェクトの月は1月が「0」となっているため、1月だから「1」を設定すると実際には2月を設定してしまうことになるので気を付けよう。
なお、月の定数には「UNDECIMBER」という定数があるが、これは太陰暦で使用する定数であるため、一般的にはあまり使用することはないだろう。
SimpleDateFormatクラス(java.text.SimpleDateFormat)
SimpleDateFormatクラスは日付書式を簡単に設定できるクラスだ。先ほどののCalendarクラスのサンプルプログラムを見てほしい。
プログラムの「getCalString()」というクラスで年月日をそれぞれ抽出して文字列変換しているが、そのような手間をかけなくてもSimpleDateFormatクラスを使うことで簡単に表示することができる。
主なコンストラクタ
コンストラクタ |
内容 |
SimpleDateFormat() |
デフォルトの書式で日付パターンが設定される。 |
SimpleDateFormat(String patern) |
指定した書式で日付パターンが設定される。 |
主なメソッド
戻り値の型 |
メソッド |
内容 |
void |
applyPattern(String pattern) |
指定された日付書式を適用する。 |
StringBuffer |
format(Date dt) |
指定された日付書式を適用して文字列(StringBuffer)で表示する。 |
日付書式について
SimpleDateFormatでは日付書式を指定して値を取得することができる。日付書式には次の種類があるので、目を通してもらいたい。
書式 |
内容 |
G |
紀元 |
y |
年 |
M |
月 |
w |
年における週 |
W |
月における週 |
D |
年における日 |
d |
月における日 |
F |
月における曜日 |
E |
曜日 |
サンプルプログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import java.util.Calendar; import java.text.SimpleDateFormat; public class Main { public static void main(String args[]) { //カレンダーを生成 Calendar cal = Calendar.getInstance(); //フォーマットを設定して出力 SimpleDateFormat sdf = new SimpleDateFormat("[1] y/M/d"); System.out.println(sdf.format(cal.getTime())); //フォーマットを変更 sdf.applyPattern("[2] yyyy/MM/dd"); System.out.println(sdf.format(cal.getTime())); sdf.applyPattern("[3] yyyy/MM/dd (E)"); System.out.println(sdf.format(cal.getTime())); sdf.applyPattern("[4] G yyyy年MM月dd日"); System.out.println(sdf.format(cal.getTime())); sdf.applyPattern("[5] yyyy年MM月dd日 は今年w週目"); System.out.println(sdf.format(cal.getTime())); sdf.applyPattern("[6] yyyy年MM月dd日 は今月W週目"); System.out.println(sdf.format(cal.getTime())); sdf.applyPattern("[7] yyyy年MM月dd日 は今年D日目"); System.out.println(sdf.format(cal.getTime())); sdf.applyPattern("[8] yyyy年MM月dd日 E曜日はF回目のE曜日"); System.out.println(sdf.format(cal.getTime())); } } |
実行結果
1 2 3 4 5 6 7 8 |
[1] 2016/6/16 [2] 2016/06/16 [3] 2016/06/16 (木) [4] 西暦 2016年06月16日 [5] 2016年06月16日 は今年25週目 [6] 2016年06月16日 は今月3週目 [7] 2016年06月16日 は今年168日目 [8] 2016年06月16日 木曜日は3回目の木曜日 |
プログラムの説明
それではサンプルプログラムを簡単に説明してみよう。
- [1]コンストラクタで書式を指定してSimpleDateFormatを生成する。
- [2]年月日の書式を設定する。「MM」とすることで「6月」を「06」月と0埋めして表示できる。
- [3]書式で曜日を設定する。
- [4]紀元を表示する。
- [5]今年に入って何週目かを表示する。
- [6]今月に入って何週目かを表示する。
- [7]今年に入って何日目かを表示する。
- [8]今月に入って、該当する曜日が何回目かを表示している。
日付の基本をおさえておこう
javaの基本的な日付に関するクラスを紹介したが、いかがだったろうか?
このページを確認してもらえれば、日付に関して必要なところはほとんど押さえられるはずだ。Javaプログラミングにおいて、日付はどのようなシステムでも扱うことなので、基本的なことはしっかりとおさえておくようにしよう。