( 本記事の目次 )
DateTimeFormatterの利用
先ほどのサンプル(Sample1.java)のparse()
メソッドでは、テキスト文字列をもとに、目的の日付オブジェクトを取得できました。しかし、引数の文字列は注意が必要です。たとえば、7行目のparse()
メソッドの引数を次のように修正したとします。
(現行) 7. LocalDate dateP = LocalDate.parse("2015-10-01"); (修正後) //日を「01」→「1」に修正 7. LocalDate dateP = LocalDate.parse("2015-10-1");
修正後のコードでもコンパイルは成功しますが、実行時にDateTimeParseException
エラーが発生します。日付/時間を表すテキスト文字列は、有効な日付および、有効な区切り文字で表している必要があり、DateTimeFormatter
クラスの定数(事前定義されたフォーマッタ)を使って解析されます。
DateTimeFormatter
クラスの主なフォーマッタは表3のとおりです。
定数名 | 説明 | 例 |
---|---|---|
ISO_DATE | オフセット付きまたはオフセットなしの日付に対し、書式設定や解析を行うISO日付フォーマッタ |
2011-12-03 2011-12-03+01:00 |
ISO_TIME | オフセット付きまたはオフセットなしの時間に対し、書式設定や解析を行うISO時間フォーマッタ |
10:15 10:15:30 10:15:30+01:00 |
ISO_DATE_TIME | オフセット付きまたはオフセットなしの日付/時間に対し、書式設定や解析を行うISO日付/時間フォーマッタ |
2011-12-03T10:15:30 2011-12-03T10:15:30+01:00 |
また、独自のフォーマッタを使用して、テキスト文字列から日付/時間オブジェクトを取得することも可能です。DateTimeFormatter
クラスには、指定されたパターンを使用してフォーマッタを作成するためのofPattern()
メソッドが提供されています。
次のサンプル(Sample2.java)では、事前定義されたフォーマッタと独自フォーマッタを使用しています。
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class Sample2 { public static void main(String[] args) { LocalDateTime dateTime1 = LocalDateTime.now(); DateTimeFormatter fmt1 = DateTimeFormatter.ISO_DATE; System.out.println("now() : " + dateTime1); System.out.println("fmt1.format() : " + fmt1.format(dateTime1)); System.out.println("dateTime1.format() : " + dateTime1.format(fmt1)); DateTimeFormatter fmt2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); String target = "2015/10/01 21:03:20"; LocalDateTime dateTime2 = LocalDateTime.parse(target, fmt2); System.out.println("ofPattern() : " + dateTime2); } }
now() : 2015-11-16T16:28:42.733 fmt1.format() : 2015-11-16 dateTime1.format() : 2015-11-16 ofPattern() : 2015-10-01T21:03:20
6行目ではnow()
メソッドを使用して、LocalDateTime
オブジェクトを作成しています。また、7行目では、DateTimeFormatter
クラスのISO_DATE
定数を指定し、事前定義されたフォーマッタを取得しています。8行目では、日付/時刻をそのまま出力していますが、9行目では、7行目で取得したフォーマッタのformat()
メソッドにLocalDateTime
オブジェクトを指定することで、日付のみ表示しています。10行目では、LocalDateTime
オブジェクトのformat()
メソッドにフォーマッタを指定しています。このように、format
メソッドは、両方のクラスに提供されています。
また、12〜13行目では、ofPattern()
メソッドの引数に独自のパターンであるyyyy/MM/dd HH:mm:ss
を指定して、DateTimeFormatter
オブジェクトを取得しています。15行目では、parse()
メソッドに解析したい文字列と、取得したDateTimeFormatter
オブジェクトを指定しています。
日付/時間の加減算
Java SE 8以前にも、日付/時間の演算処理に最低限必要なAPIは用意されていましたが、使いやすいものではありませんでした。Date and Time APIでは、直感的に使用できるメソッドが多数用意されています。
表4は、LocalDate
クラスの加算を行うメソッドです。
メソッド名 | 説明 |
---|---|
LocalDate plusDays(long daysToAdd) | 指定された日数を加算した、このLocalDateのコピーを返す |
LocalDate plusMonths(long monthsToAdd) | 指定された月数を加算した、このLocalDateのコピーを返す |
LocalDate plusWeeks(long weeksToAdd) | 指定された週数を加算した、このLocalDateのコピーを返す |
LocalDate plusYears(long yearsToAdd) | 指定された年数を加算した、このLocalDateのコピーを返す |
同様に、減算を行うメソッドとして、minusDays()
などの「minusXXX()
」メソッドも提供されています。
次のサンプル(Sample3.java)は、LocalDate
オブジェクトに加算を行っています。
import java.time.LocalDate; public class Sample3 { public static void main(String[] args) { LocalDate date = LocalDate.of(2015, 10, 1); System.out.println("date : " + date); System.out.println("3日後 : " + date.plusDays(3)); System.out.println("5ケ月後 : " + date.plusMonths(5)); System.out.println("2週間後 : " + date.plusWeeks(2)); System.out.println("10年後 : " + date.plusYears(10)); System.out.println("date : " + date); } }
date : 2015-10-01 3日後 : 2015-10-04 5ケ月後 : 2016-03-01 2週間後 : 2015-10-15 10年後 : 2025-10-01 date : 2015-10-01
7~10行目では、LocalDate
オブジェクトに日、月、週、年の加算を行っています。しかし、6行目と11行目を見ると、加算前と加算後でdate
変数が表している日付は同じです。Date and Time APIの各クラスは不変オブジェクトであるため、オブジェクトが保持する情報が変化するわけではありません。加算後のオブジェクトを取得したい場合は、各メソッドの戻り値を変数に代入してください。以下は、加算した結果をdate
変数に再代入するように、7行目を修正した例です。
(現行) 7. System.out.println("3日後 : " + date.plusDays(3)); (修正後) 7. date = date.plusDays(3); 8. System.out.println("3日後 : " + date);