【Java初心者用】今日の日付を表示する(4つのクラス)
Javaのプログラムでは日時のデータをよく利用します。曜日や時間を求めて表示するメッセージを切り替えたり、色々な場面で利用されます。しかし、「Calendarクラス」や「SimpleDateFormatクラス」などが用意されており、どれを使用すれば良いのか初心者は戸惑うことでしょう。
今回は、Java7まで使われていた「Calendarクラス」と「SimpleDateFormatクラス」、Java8から導入された新しい「LocalDateTimeクラス」と「DateTimeFormatterクラス」の使い方を説明します。
なお、それぞれには多数のメソッドが定義されていますが、今回は基本的な使い方として「今日の日付を求める」処理だけに限定して、4つのクラスを使ったプログラムを別々に紹介します。それぞれの使い方をぜひ比較しながら確認して下さい。
まず、この記事は以下のような人を対象としています。
対象者・Javaの勉強を始めた人
・以前から使われている方法で日付の求め方を知りたい人
・新しい方法で日付の求めたかを知りたい人
この記事を読むと、次のようなことが理解できるようになります。
この記事を読むとできること・Calendarクラスの使い方を知ることができる
・SimpleDateFormatの使い方を知ることができる
・LocalDateTimeの使い方を知ることができる
・DateTimeFormatterの使い方を知ることができる
日付を求める時に古い方法と新しい方法があると聞いたのですが?
日時の扱い方はJava8から全く新しく変わりました。
では、新しい方法だけ覚えれば良いのでしょうか?
以前の方法もまだ使われているので、一応両方の使い方を覚えておいた方が良いでしょう!! 今回はこれまでの方法と新しい方法の使い方について説明します。
日時の求め方
日時を求める場合、数値として求める場合と文字列として求める場合で、以下のように5つのクラスを利用することができます。しかし、Dateクラスで日時を求める方法は現在非推奨となっているので、実際は4種類となります。
プログラムで日時を求める必要がある場合、数値として求めたいのか、それとも文字列として求めたいのかを判断して、それぞれのクラスを使い分ける必要があります。
画面上にメッセージとして日付を表示する場合、数値を求めるクラスを利用すると、文字列として連結する手間が増えます。また、何かの計算をするために数値として日付を求めたいのに、文字列として求めるクラスを利用すると、数値に変換する手間が増えます。したがって、どのような形式のデータを使いたいのか、きちんと把握しておく必要があります。
ただし、クラスを覚えるのが面倒だという場合は、数値として求めるクラスの使い方だけを覚えておけば良いでしょう。直接計算で使用でき、文字列としてい利用したい場合は単純に文字列連結すれば良いので、使い勝手が良いと言えます。
Calendarクラス
まず、Calendarクラスで良く利用するメソッドについて説明します。
getInstance()メソッド
このメソッドを実行すると、その瞬間の日時のデータを格納したCalenderオブジェクトを取得することができます。なお、このメソッドはクラスメソッドなので、実行する場合は「Calendar.getInstance()」と記述します。
get()メソッド
getInstance()メソッドで取得したCalendarオブジェクト内には西暦、月、日、曜日、時、分、秒など日時に関する様々な情報が格納されています。ユーザはそれらの中から使用したい情報を、このget()メソッドを使って取り出します。()内には取り出したい情報をint型の値として指定します。メソッドを実行した結果返される各種データは全てint型となります。なお、()内でint型の値を指定する場合、0や1では何を指定しているのか分かりづらいため、「YEAR」や「HOUR」などの定数(クラス定数)が用意されているので、その定数を指定します。これらの定数はクラス定数なので、指定する場合は「Calendar.定数」とします。主な定数は以下の通りです。
set()メソッド
set()メソッドは引数に年、月、日などの値を整数で指定するとその指定した値を使って新しいCalendarオブジェクトを作ります。ただし、set()メソッドだけで全く新しいCalendarオブジェクトを作ることはできないので、まずはgetInstance()メソッドで現在のCalendarオブジェクトを取得し、そのCalendarオブジェクトに新しい情報を設定して作り替える流れになります。
今日の日付を求める処理の流れ
Calendarクラスを利用して日時のデータを扱う場合、プログラムの流れは次のようになります。
- getInstance()メソッドでその時の日時のデータ(Calendarオブジェクト)を取得する
- get()メソッドを使用して、必要なデータをCalendarオブジェクトから取り出す
今回は、「〇年〇月〇日(〇)」という形式で結果を表示するので、扱うデータは年、月、日、曜日の4種類となります。
サンプルプログラムは以下の通りです。
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 |
package today; import java.util.Calendar; public class TodayCalendar { public static void main(String[] args) { // 現在の日時を取得 Calendar cal = Calendar.getInstance(); // 西暦、月、日、曜日を取得 int year = cal.get(Calendar.YEAR); int month = cal.get(Calendar.MONTH)+1; int date = cal.get(Calendar.DATE); int day = cal.get(Calendar.DAY_OF_WEEK); String dayJpn = getDayJpn(day); // 日本語曜日を求めるメソッドを実行 // 結果の表示 System.out.printf("今日の日付:%d年%d月%d日%s%n",year,month,date,dayJpn); } public static String getDayJpn(int day) { String dayJpn = ""; switch (day) { case Calendar.MONDAY: dayJpn = "(月)"; break; case Calendar.TUESDAY: dayJpn = "(火)"; break; case Calendar.WEDNESDAY: dayJpn = "(水)"; break; case Calendar.THURSDAY: dayJpn = "(木)"; break; case Calendar.FRIDAY: dayJpn = "(金)"; break; case Calendar.SATURDAY: dayJpn = "(土)"; break; case Calendar.SUNDAY: dayJpn = "(日)"; break; } return dayJpn; } } |
Calendarクラスを利用する場合の注意点は、「月を求めた場合に得られる値は実際の月よりも1小さい」ということです。したがって、13行目のように「get(Calendar.MONTH)」を実行する場合は「+1」を忘れないようにしてください。
また、曜日も1,2のような数値が返されますが、Calendarクラスには曜日を表す定数がEnum型(列挙型)で定義されているので、その定数を利用した方がプログラムの意味が理解しやすくなります。なお、日本語の曜日を求めるメソッドを別途定義していますが、main()メソッド内に記述しても構いません。
12行目から14行目で年、月、日の値を個別に整数として取得できたので、19行目でprintf()メソッドを利用して文字列として表示してます。
SimpleDateFormatクラス
SimpleDateFormatクラスは、書式を指定して日時のデータを文字列で取得するためのクラスです。日時を取得する際に利用する主なメソッドは以下の通りです。
書式で指定できる文字
SimpleDateFormatクラスを利用する場合は、書式を指定するためにどのような文字が利用できるか確認しておかなければなりません。どの文字を利用すると、日時の中の何のデータが取り出せるのか覚えておかなければなりません。主な文字と取り出せる情報の対応は以下の通りです。
format()メソッド
このメソッドは()内に指定したDate型のオブジェクト(通常は現在の日時)を、指定した書式の文字列として返します。利用する書式はあらかじめコンストラクタの引数として指定しておきます。
今日の日付を求める処理の流れ
SimpleDateFormatクラスを利用して日時のデータを扱う場合、プログラムの流れは次のようになります。
- SimpleDateFormatクラスのコンストラクタに書式を文字列として指定し、オブジェクトを作成する
- format()メソッドに現在の日時オブジェクト指定し、書式にあった文字列を取得する
サンプルプログラムは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package today; import java.text.SimpleDateFormat; import java.util.Date; public class TodaySImpleDateFormat { public static void main(String[] args) { // 現在の日時を取得 Date now = new Date(); // 書式を指定した文字列を作成 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日(E)"); // 結果の表示 System.out.printf("今日の日付:"+sdf.format(now)); } } |
10行目でDateクラスを利用して現在の日時を求めています。現在はDateクラスに用意されている各種情報を取得するメソッドは非推奨となっていますが、コンストラクタを利用していDateオブジェクトを取得することは可能です。
13行目でSimpleDateFormatクラスのコンストラクタに取得したい書式を文字列として指定し、SimpleDateFormatオブジェクトを作成しています。
16行目のformat()メソッドの引数に作成済みのDateオブジェクトを指定すると、指定した書式の文字列を取得することができます。
このように単に日時を文字列として扱いたい時はSimpleDateFormatクラスを利用した方がプログラムは簡単になります。
LocalDateTimeクラス
LocalDateTimeクラスはJava8から導入された全く新しい日時を扱うためのクラスのひとつです。Calendarクラスクラスは「java.utilパッケージ」のうちのひとつのクラス(機能)でしたが、このLocalDateTimeクラスは日時専用の「java.timeパッケージ」に含まれるクラスです。わざわざ日時を扱うために新しいパッケージが作成され、より様々な処理ができるようになっています。
多くのメソッドが用意されていますが、今回は基本的なメソッドのみ取り上げます。
LocalDateTimeクラスでは、取り出すデータ毎に専用のメソッドが用意されています。月を取り出す場合は、2種類用意されていますが、単純に値を取得したい場合は「getMonthValue()メソッド」を利用すれば良いでしょう。なお、Calendarクラスと異なり取り出される月の値はそのままの値なので、「+1」する必要はありません。Calendarクラスでは「+1」の記述を忘れてしまい、潜在的なバグになる危険性がありますが、このLocalDateTimeクラスでは「+1」する必要がないので、安心して利用することができます。
今日の日付を求める処理の流れ
LocalDateTimeクラスを利用して日時のデータを扱う場合、プログラムの流れは次のようになります。
- now()メソッドでその時の日時のデータ(LocalDateTimeオブジェクト)を取得する
- get~()メソッドを使用して、必要なデータをLocalDateTimeオブジェクトから取り出す
サンプルプログラムは以下の通りです。
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 |
package today; import java.time.DayOfWeek; import java.time.LocalDateTime; public class TodayLocalDateTime { public static void main(String[] args) { // 現在の日時を取得 LocalDateTime now = LocalDateTime.now(); // 西暦、月、日、曜日を取得 int year = now.getYear(); int month = now.getMonthValue(); int date = now.getDayOfMonth(); DayOfWeek day = now.getDayOfWeek(); String dayJpn = ""; switch (day) { case MONDAY: dayJpn = "(月)"; break; case TUESDAY: dayJpn = "(火)"; break; case WEDNESDAY: dayJpn = "(水)"; break; case THURSDAY: dayJpn = "(木)"; break; case FRIDAY: dayJpn = "(金)"; break; case SATURDAY: dayJpn = "(土)"; break; case SUNDAY: dayJpn = "(日)"; break; } // 結果の表示 System.out.printf("今日の日付:%d年%d月%d日%s%n", year, month, date, dayJpn); } } |
なお、このサンプルプログラムでは日本語表記の曜日を求める処理をmain()メソッド内に記述していますが、Calendarクラスを利用したサンプルプログラムのように別途メソッドに分けて記述しても構いません。
曜日を取得するgetDayOfWeek()メソッドの戻り値はEnum型(列挙型)となります。Calendarクラスの場合、「Calendar.MONDAY」とクラス名の「Calendar.」を定数の前に記述しなければなりませんでしたが、LocalDateTimeクラスの場合は「MONDAY」と定数のみを記述するだけで構いません。
DateTimeFormatterクラス
最後に日時を文字列として取り出すDateTimeFormatterクラスについて説明します。
今日の日付を求める処理の流れ
DateTimeFormatterクラスを利用して日時のデータを扱う場合、プログラムの流れは次のようになります。SimpleDateFormatクラスを利用する場合のおおまかな流れは変わりません。
- DateTimeFormatterクラスのクラスメソッドであるofPattern()メソッドに書式を文字列として指定し、オブジェクトを作成する
- format()メソッドに現在の日時オブジェクト指定し、書式にあった文字列を取得する
サンプルプログラムは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package today; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class TodayDateTimeFormatter { public static void main(String[] args) { // 現在の日時を取得 LocalDateTime now = LocalDateTime.now(); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日(E)"); // 結果の表示 System.out.printf("今日の日付:" + dtf.format(now)); } } |
まず、10行目で現在の日付データをLocalDateTimeクラスを使って作成しています。12行目では文字列の書式を指定しています。なお、書式で利用できる文字はSimpleDateFormatクラスと同じになるので、ここでは省略します。最後に15行目のformat()メソッドで実際に書式の通りに文字列を取得してます。
まとめ
今回は、日付を扱うために利用できる4種類のクラスの使い方について説明しました。では、実際に日付を扱うプログラムを作る場合にどれを利用すれば良いのでしょうか?
オススメはJava8から導入されたLocalDateTimeクラスとDateTimeFormatterクラスを利用するプログラムとなります。新しく作成されたクラスのため、この記事では説明していませんが便利なメソッドが多数用意されています。したがって新しく覚えるのならばこの2つのクラスが良いでしょう。
しかし、CalendarクラスとSimpleDateFormatクラスを全く勉強しなくても良いかというとそうではありません。例えば、他のプログラマが作成したプログラムをメンテナンスする場合、これらのクラスを使用している可能性があります。全く知識がないと何も対応することができないので、基本的な使い方程度は知っておく必要があります。
・日時を扱うクラスは全部で4種類存在する
・4種類のクラスは、数値を返すか文字列を返すかの2種類に分類することができる
・新しく覚える場合はLocalDateTimeクラスとSimpleDateFormatクラスがおすすめ
今日の結果を表示するだけでも4種類のクラスを利用して違ったプログラムを作成することができます。いかがでしたか?
今までは一つのクラスでプログラムを作成したら、それで満足していました。
改めて、色々な作り方があると知りました!!
どれを使用してもプログラムとしては正解です。
是非、これからも他の方法でプログラムが作れないか考えてみて下さい!!