概要
Joda-Timeを使った日付処理のまとめです。
(なおJava8であればTime APIがあるのでJoda-Timeを使用する必要はありません)
環境
下記の環境で動作確認を行いました。
- Windows7 (64bit)
- Java 1.8.0_45
- [Joda-Time] (http://www.joda.org/joda-time/) 2.8.1
参考
下記のサイトを参考にさせて頂きました。
Joda
- [Joda-Time 2.8.1 API] (http://www.joda.org/joda-time/apidocs/overview-summary.html)
blog
- [Javaで面倒くさい日付の扱いを簡単にするライブラリ「Joda-Time」 期間編] (http://shinsuke789.hatenablog.jp/entry/2013/08/06/195436)
Stack Overflow
- [PeriodFormatter not showing days] (http://stackoverflow.com/questions/26291271/periodformatter-not-showing-days)
その他
- [Joda-Time - IBM developerWorks 日本語版] (http://www.ibm.com/developerworks/jp/java/library/j-jodatime.html)
- [JSR 310 JavaのDate/Time API - InfoQ] (http://www.infoq.com/jp/news/2010/03/jsr-310)
- [Java 8 Date/Time API Tutorial - Examples Java Code Geeks] (http://examples.javacodegeeks.com/core-java/java-8-datetime-api-tutorial/)
DateTimeを使った日付処理
DateTime
はUTCからのオフセットやタイムゾーンを持つ日時を表すクラスです。似た名前のLocalDateTime
はUTCからのオフセットやタイムゾーンを持ちません。
サンプルコードの日付フォーマットについて
以降のサンプルコードで使用する日付フォーマットは下記の通りです。とくに断りが無い場合は日付をこのフォーマットで文字列にします。
DateTimeFormatter DEF_FMT = DateTimeFormat.forPattern("G yyyy-MM-dd(E) aHH:mm:ss.SSS ZZ.");
これも以降のサンプルコードで使用する期間用フォーマットです。
PeriodFormatter PERIOD_FMT = new PeriodFormatterBuilder()
.printZeroAlways()
.appendYears().appendSuffix(" year ", " years ")
.appendMonths().appendSuffix(" month ", " months ")
.appendWeeks().appendSuffix(" week ", " weeks ")
.appendDays().appendSuffix(" day ", " days ")
.appendHours().appendSuffix(" hour ", " hours ")
.appendMinutes().appendSuffix(" minutes ")
.appendSeconds().appendSuffix(" seconds ")
.toFormatter();
インスタンスの生成
コンストラクタ
DateTime dt1 = new DateTime();
System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.897 +09:00.
DateTime dt2 = new DateTime(2006, 1, 2, 15, 4);
DateTime dt3 = new DateTime(2006, 1, 2, 15, 4, 5);
DateTime dt4 = new DateTime(2006, 1, 2, 15, 4, 5, 666);
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2006-01-02(月) 午後15:04:00.000 +09:00.
System.out.println(DEF_FMT.print(dt3));
// ⇒ 西暦 2006-01-02(月) 午後15:04:05.000 +09:00.
System.out.println(DEF_FMT.print(dt4));
// ⇒ 西暦 2006-01-02(月) 午後15:04:05.666 +09:00.
now()
現在日時を持つDateTime
インスタンスを生成します。
DateTime dt5 = DateTime.now();
System.out.println(DEF_FMT.print(dt5));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.858 +09:00.
parse()
日付を表現する文字列を解析してDateTime
インスタンスを生成します。
DateTime pd1 = DateTime.parse("2006-01-02");
System.out.println(DEF_FMT.print(pd1));
// ⇒ 西暦 2006-01-02(月) 午前00:00:00.000 +09:00.
DateTime pd2 = DateTime.parse("2006-01-02T15:04:05");
System.out.println(DEF_FMT.print(pd2));
// ⇒ 西暦 2006-01-02(月) 午後15:04:05.000 +09:00.
DateTime pd3 = DateTime.parse("20060102 150405", DateTimeFormat.forPattern("yyyyMMdd HHmmss"));
System.out.println(DEF_FMT.print(pd3));
// ⇒ 西暦 2006-01-02(月) 午後15:04:05.000 +09:00.
タイムゾーンを指定
DateTime
インスタンス生成時に任意のタイムゾーンを指定することができます。
指定しない場合はデフォルトのタイムゾーンが使用されます。
DateTimeZone tokyo = DateTimeZone.forID("Asia/Tokyo");
DateTime dt6 = new DateTime(tokyo);
System.out.println(DEF_FMT.print(dt6));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.909 +09:00.
DateTimeZone nyc = DateTimeZone.forID("America/New_York");
DateTime dt7 = new DateTime(nyc);
System.out.println(DEF_FMT.print(dt7));
// ⇒ 西暦 2015-07-08(水) 午前08:52:23.911 -04:00.
デフォルトのタイムゾーン
DateTime dt1 = DateTime.now();
DateTimeZone defaultZone = dt1.getZone();
System.out.println(defaultZone);
// ⇒ Asia/Tokyo
暦
DateTime
インスタンス生成時に任意の暦を指定することができます。
Chronology gregorian = GregorianChronology.getInstance();
DateTime dt8 = new DateTime(gregorian);
System.out.println(DEF_FMT.print(dt8));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.912 +09:00.
デフォルトの暦
DateTime dt1 = DateTime.now();
Chronology defaultChrono = dt1.getChronology();
System.out.println(defaultChrono);
// ⇒ ISOChronology[Asia/Tokyo]
フォーマット
DateTime
インスタンスを指定した書式の文字列にフォーマットします。
事前定義フォーマット
DateTimeFormat
クラスには事前定義されたフォーマットがあります。
DateTime dt1 = DateTime.now();
DateTimeFormatter fullFmt = DateTimeFormat.fullDateTime()
DateTimeFormatter longFmt = DateTimeFormat.longDateTime()
DateTimeFormatter mediumFmt = DateTimeFormat.mediumDateTime()
DateTimeFormatter shortFmt = DateTimeFormat.shortDateTime()
System.out.println(fullFmt.print(dt1));
// ⇒ 2015年7月8日 21時52分23秒 JST
System.out.println(longFmt.print(dt1));
// ⇒ 2015/07/08 21:52:23 JST
System.out.println(mediumFmt.print(dt1));
// ⇒ 2015/07/08 21:52:23
System.out.println(shortFmt.print(dt1));
// ⇒ 15/07/08 21:52
フォーマットのカスタマイズ
カスタマイズした書式でフォーマットすることができます。
カスタマイズの方法はforPattern()
,forStyle
でパターンを指定する方法とDateTimeFormatterBuilder
を使用する方法があります。
DateTime dt1 = DateTime.now();
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").print(dt1));
// ⇒ 2015-07-08 21:52:23
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").print(dt1));
// ⇒ 2015-07-08 21:52:23.924
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSSZ").print(dt1));
// ⇒ 2015-07-08 21:52:23.924+0900
System.out.println(DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSSZZ").print(dt1));
// ⇒ 2015-07-08 21:52:23.924+09:00
System.out.println(DateTimeFormat.forPattern("G yyyy-MM-dd(E) aHH:mm:ss.SSS ZZ.").print(dt1));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.924 +09:00.
forStyle
は2文字でパターンを指定します。パターンに使用できる文字は「F
=Full、L
=Long、M
=Medium、S
=Short、-
=非表示」です。
1文字目に日付、2文字目に時刻のパターンを指定します。
DateTime dt1 = DateTime.now();
System.out.println(DateTimeFormat.forStyle("FF").print(dt1));
// ⇒ 2015年7月8日 21時52分23秒 JST
System.out.println(DateTimeFormat.forStyle("LL").print(dt1));
// ⇒ 2015/07/08 21:52:23 JST
System.out.println(DateTimeFormat.forStyle("MM").print(dt1));
// ⇒ 2015/07/08 21:52:23
System.out.println(DateTimeFormat.forStyle("SS").print(dt1));
// ⇒ 15/07/08 21:52
System.out.println(DateTimeFormat.forStyle("LS").print(dt1));
// ⇒ 2015/07/08 21:52
System.out.println(DateTimeFormat.forStyle("L-").print(dt1));
// ⇒ 2015/07/08
DateTimeFormatterBuilder
を使用してフォーマットを組み立てることができます。
DateTime dt1 = DateTime.now();
DateTimeFormatter buildFmt = new DateTimeFormatterBuilder()
.appendEraText()
.appendLiteral(" ")
.appendYear(4, 4)
.appendLiteral("年")
.appendMonthOfYear(2)
.appendLiteral("月")
.appendDayOfMonth(2)
.appendLiteral("日")
.appendLiteral(" ")
.appendDayOfWeekText()
.appendLiteral(" ")
.toFormatter();
System.out.println(buildFmt.print(dt1));
// ⇒ 西暦 2015年07月08日 水曜日
日付の計算
plus
plus
系のメソッドを使って日時の加算を行います。
DateTime dt1 = DateTime.now();
System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.949 +09:00.
/*10分足す*/
dt1 = dt1.plusMinutes(10);
System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-08(水) 午後22:02:23.949 +09:00.
/*2時間足す*/
dt1 = dt1.plusHours(2);
System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-09(木) 午前00:02:23.949 +09:00.
/*3日足す*/
dt1 = dt1.plusDays(3);
System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-12(日) 午前00:02:23.949 +09:00.
minus
minus
系のメソッドを使って日時の減算を行います。
DateTime dt2 = DateTime.now();
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.950 +09:00.
/*10分引く*/
dt2 = dt2.minusMinutes(10);
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2015-07-08(水) 午後21:42:23.950 +09:00.
/*2時間引く*/
dt2 = dt2.minusHours(2);
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2015-07-08(水) 午後19:42:23.950 +09:00.
/*3日引く*/
dt2 = dt2.minusDays(3);
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2015-07-05(日) 午後19:42:23.950 +09:00.
with
with
系のメソッドを使って特定のフィールドの日時を変更します。
DateTime dt3 = DateTime.now();
System.out.println(DEF_FMT.print(dt3));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.950 +09:00.
/*時、分、秒、ミリ秒を0にセット*/
dt3 = dt3.withTime(0, 0, 0, 0);
System.out.println(DEF_FMT.print(dt3));
// ⇒ 西暦 2015-07-08(水) 午前00:00:00.000 +09:00.
/*年を2016にセット*/
dt3 = dt3.withYear(2016);
System.out.println(DEF_FMT.print(dt3));
// ⇒ 西暦 2016-07-08(金) 午前00:00:00.000 +09:00.
/*月を12にセット*/
dt3 = dt3.withMonthOfYear(12);
System.out.println(DEF_FMT.print(dt3));
// ⇒ 西暦 2016-12-08(木) 午前00:00:00.000 +09:00.
round
round
系のメソッドを使って日付の丸め処理を行います。
DateTime dt4 = DateTime dt4 = new DateTime(2015, 7, 8, 12, 35, 25, 999);
System.out.println(DEF_FMT.print(dt4));
// ⇒ 西暦 2015-07-08(水) 午後12:35:25.999 +09:00.
DateTime dt5 = dt4.hourOfDay().roundFloorCopy();
System.out.println(DEF_FMT.print(dt4));
// ⇒ 西暦 2015-07-08(水) 午後12:00:00.000 +09:00.
dt5 = dt4.minuteOfHour().roundFloorCopy();
System.out.println(DEF_FMT.print(dt4));
// ⇒ 西暦 2015-07-08(水) 午後12:35:00.000 +09:00.
dt5 = dt4.hourOfDay().roundCeilingCopy();
System.out.println(DEF_FMT.print(dt4));
// ⇒ 西暦 2015-07-08(水) 午後13:00:00.000 +09:00.
dt5 = dt4.minuteOfHour().roundCeilingCopy();
System.out.println(DEF_FMT.print(dt4));
// ⇒ 西暦 2015-07-08(水) 午後12:36:00.000 +09:00.
roundサンプル
year()
2015-05-15 11:30:00
、2015-06-15 11:30:00
、2015-07-15 11:30:00
の日時に対して3種類の丸め処理を行った結果を下表にまとめました。
new DateTime(2015, 5, 15, 11, 30, 00, 000).year().roundFloorCopy();
new DateTime(2015, 5, 15, 11, 30, 00, 000).year().roundCeilingCopy()
new DateTime(2015, 5, 15, 11, 30, 00, 000).year().roundHalfFloorCopy()
new DateTime(2015, 6, 15, 11, 30, 00, 000).year().roundFloorCopy();
new DateTime(2015, 6, 15, 11, 30, 00, 000).year().roundCeilingCopy()
new DateTime(2015, 6, 15, 11, 30, 00, 000).year().roundHalfFloorCopy()
new DateTime(2015, 7, 15, 11, 30, 00, 000).year().roundFloorCopy();
new DateTime(2015, 7, 15, 11, 30, 00, 000).year().roundCeilingCopy()
new DateTime(2015, 7, 15, 11, 30, 00, 000).year().roundHalfFloorCopy()
method | 2015-05-15 11:30:00 |
2015-06-15 11:30:00 |
2015-07-15 11:30:00 |
---|---|---|---|
roundFloorCopy | 2015-01-01 00:00:00 |
2015-01-01 00:00:00 |
2015-01-01 00:00:00 |
roundCeilingCopy | 2016-01-01 00:00:00 |
2016-01-01 00:00:00 |
2016-01-01 00:00:00 |
roundHalfEvenCopy | 2015-01-01 00:00:00 |
2015-01-01 00:00:00 |
2016-01-01 00:00:00 |
monthOfYear()
2015-06-15 11:30:00
、2015-06-16 11:30:00
、2015-06-17 11:30:00
の日時に対して3種類の丸め処理を行った結果を下表にまとめました。
new DateTime(2015, 6, 15, 11, 30, 00, 000).monthOfYear().roundFloorCopy();
new DateTime(2015, 6, 15, 11, 30, 00, 000).monthOfYear().roundCeilingCopy();
new DateTime(2015, 6, 15, 11, 30, 00, 000).monthOfYear().roundHalfFloorCopy();
new DateTime(2015, 6, 16, 11, 30, 00, 000).monthOfYear().roundFloorCopy();
new DateTime(2015, 6, 16, 11, 30, 00, 000).monthOfYear().roundCeilingCopy();
new DateTime(2015, 6, 16, 11, 30, 00, 000).monthOfYear().roundHalfFloorCopy();
new DateTime(2015, 6, 17, 11, 30, 00, 000).monthOfYear().roundFloorCopy();
new DateTime(2015, 6, 17, 11, 30, 00, 000).monthOfYear().roundCeilingCopy();
new DateTime(2015, 6, 17, 11, 30, 00, 000).monthOfYear().roundHalfFloorCopy();
method | 2015-06-15 11:30:00 |
2015-06-16 11:30:00 |
2015-06-17 11:30:00 |
---|---|---|---|
roundFloorCopy | 2015-06-01 00:00:00 |
2015-06-01 00:00:00 |
2015-06-01 00:00:00 |
roundCeilingCopy | 2015-07-01 00:00:00 |
2015-07-01 00:00:00 |
2015-07-01 00:00:00 |
roundHalfEvenCopy | 2015-06-01 00:00:00 |
2015-07-01 00:00:00 |
2015-07-01 00:00:00 |
2015-07-15 11:30:00
、2015-07-16 11:30:00
、2015-07-17 11:30:00
の日時に対して3種類の丸め処理を行った結果を下表にまとめました。
neww DateTime(2015, 7, 15, 11, 30, 00, 000).monthOfYear().roundFloorCopy();
neww DateTime(2015, 7, 15, 11, 30, 00, 000).monthOfYear().roundCeilingCopy();
neww DateTime(2015, 7, 15, 11, 30, 00, 000).monthOfYear().roundHalfFloorCopy();
neww DateTime(2015, 7, 16, 11, 30, 00, 000).monthOfYear().roundFloorCopy();
neww DateTime(2015, 7, 16, 11, 30, 00, 000).monthOfYear().roundCeilingCopy();
neww DateTime(2015, 7, 16, 11, 30, 00, 000).monthOfYear().roundHalfFloorCopy();
neww DateTime(2015, 7, 17, 11, 30, 00, 000).monthOfYear().roundFloorCopy();
neww DateTime(2015, 7, 17, 11, 30, 00, 000).monthOfYear().roundCeilingCopy();
neww DateTime(2015, 7, 17, 11, 30, 00, 000).monthOfYear().roundHalfFloorCopy();
method | 2015-07-15 11:30:00 |
2015-07-16 11:30:00 |
2015-07-17 11:30:00 |
---|---|---|---|
roundFloorCopy | 2015-07-01 00:00:00 |
2015-07-01 00:00:00 |
2015-07-01 00:00:00 |
roundCeilingCopy | 2015-08-01 00:00:00 |
2015-08-01 00:00:00 |
2015-08-01 00:00:00 |
roundHalfEvenCopy | 2015-07-01 00:00:00 |
2015-07-01 00:00:00 |
2015-08-01 00:00:00 |
hourOfDay()
2015-06-15 11:29:00
、2015-06-15 11:30:00
、2015-06-15 11:31:00
の日時に対して3種類の丸め処理を行った結果を下表にまとめました。
new DateTime(2015, 6, 15, 11, 29, 00, 000).hourOfDay().roundFloorCopy();
new DateTime(2015, 6, 15, 11, 29, 00, 000).hourOfDay().roundCeilingCopy();
new DateTime(2015, 6, 15, 11, 29, 00, 000).hourOfDay().roundHalfFloorCopy();
new DateTime(2015, 6, 15, 11, 30, 00, 000).hourOfDay().roundFloorCopy();
new DateTime(2015, 6, 15, 11, 30, 00, 000).hourOfDay().roundCeilingCopy();
new DateTime(2015, 6, 15, 11, 30, 00, 000).hourOfDay().roundHalfFloorCopy();
new DateTime(2015, 6, 15, 11, 31, 00, 000).hourOfDay().roundFloorCopy();
new DateTime(2015, 6, 15, 11, 31, 00, 000).hourOfDay().roundCeilingCopy();
new DateTime(2015, 6, 15, 11, 31, 00, 000).hourOfDay().roundHalfFloorCopy();
method | 2015-06-15 11:29:00 |
2015-06-15 11:30:00 |
2015-06-15 11:31:00 |
---|---|---|---|
roundFloorCopy | 2015-06-15 11:00:00 |
2015-06-15 11:00:00 |
2015-06-15 11:00:00 |
roundCeilingCopy | 2015-06-15 12:00:00 |
2015-06-15 12:00:00 |
2015-06-15 12:00:00 |
roundHalfEvenCopy | 2015-06-15 11:00:00 |
2015-06-15 11:00:00 |
2015-06-15 12:00:00 |
日付の比較
DateTime dt1 = DateTime.now();
DateTime dt2 = dt1.plusHours(1);
DateTime dt3 = dt1.minusHours(1);
System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-08(水) 午後22:04:14.745 +09:00.
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2015-07-08(水) 午後23:04:14.745 +09:00.
System.out.println(DEF_FMT.print(dt3));
// ⇒ 西暦 2015-07-08(水) 午後21:04:14.745 +09:00.
if (dt1.isEqual(dt2)) {
System.out.println("dt1 is equal dt2");
} else {
System.out.println("dt1 is not equal dt2");
// ⇒ dt1 is not equal dt2
}
if (dt1.isEqual(dt1)) {
System.out.println("dt1 is equal dt1");
// ⇒ dt1 is equal dt1
} else {
System.out.println("dt1 is not equal dt1");
}
if (dt1.isAfter(dt2)) {
System.out.println("dt1 is after dt2");
}
if (dt1.isAfter(dt3)) {
System.out.println("dt1 is after dt3");
// ⇒ dt1 is after dt3
}
if (dt1.isBefore(dt2)) {
System.out.println("dt1 is before dt2");
// ⇒ dt1 is before dt2
}
if (dt1.isBefore(dt3)) {
System.out.println("dt1 is before dt2");
}
期間の比較
Joda-Timeでは期間を表すクラスが3つあります。
Interval
Duration
Period
Interval
2つの日付から期間を生成し、2つの期間同士を比較することができます。
このクラスは、明確なインスタントによって範囲が決められた特定の期間を表現します。Interval は半開の期間です。つまり、Interval によってカプセル化された期間には、期間の開始は含まれますが、終了は除外されることを意味します。
Interval を使用するのは、時系列における特定の時点で始まり、特定の時点で終了する期間を表現しなければならない場合です。
[Joda-Time - IBM developerWorks 日本語版] (http://www.ibm.com/developerworks/jp/java/library/j-jodatime.html)
abuts()
abuts
で2つの期間が隣接しているか確認することができます。
DateTime dt1 = new DateTime(2015, 7, 8, 0, 0, 0, 0);
DateTime dt2 = new DateTime(2015, 7, 9, 23, 59, 59, 0);
Interval interval1 = new Interval(dt1, dt2);
System.out.println(interval1.toString());
// ⇒ 2015-07-08T00:00:00.000+09:00/2015-07-09T23:59:59.000+09:00
DateTime dt3 = new DateTime(2015, 7, 10, 0, 0, 0, 0);
DateTime dt4 = new DateTime(2015, 7, 11, 23, 59, 59, 0);
Interval interval2 = new Interval(dt3, dt4);
System.out.println(interval2.toString());
// ⇒ 2015-07-10T00:00:00.000+09:00/2015-07-11T23:59:59.000+09:00
if (interval1.abuts(interval2)) {
System.out.println("abuts");
} else {
System.out.println("not abuts");
// ⇒ not abuts
}
dt2 = dt2.plusSeconds(1);
interval1 = new Interval(dt1, dt2);
if (interval1.abuts(interval2)) {
System.out.println("abuts");
// ⇒ abuts
} else {
System.out.println("not abuts");
}
gap()
gap
で2つの期間の隔たりを確認することができます。
DateTime dt1 = new DateTime(2015, 7, 8, 0, 0, 0, 0);
DateTime dt2 = new DateTime(2015, 7, 10, 0, 0, 0, 0);
Interval interval1 = new Interval(dt1, dt2);
System.out.println(interval1.toString());
// ⇒ 2015-07-08T00:00:00.000+09:00/2015-07-10T00:00:00.000+09:00
DateTime dt3 = new DateTime(2015, 7, 13, 0, 0, 0, 0);
DateTime dt4 = new DateTime(2015, 7, 14, 0, 0, 0, 0);
Interval interval2 = new Interval(dt3, dt4);
System.out.println(interval2.toString());
// ⇒ 2015-07-13T00:00:00.000+09:00/2015-07-14T00:00:00.000+09:00
Interval gaps = interval1.gap(interval2);
if (gaps != null) {
System.out.println(gaps.toString());
// ⇒ 2015-07-10T00:00:00.000+09:00/2015-07-13T00:00:00.000+09:00
} else {
System.out.println("not gaps");
}
overlap()
overlap
で2つの期間の重なった範囲を確認することができます。
DateTime dt1 = new DateTime(2015, 7, 8, 0, 0, 0, 0);
DateTime dt2 = new DateTime(2015, 7, 12, 0, 0, 0, 0);
Interval interval1 = new Interval(dt1, dt2);
System.out.println(interval1.toString());
// ⇒ 2015-07-08T00:00:00.000+09:00/2015-07-12T00:00:00.000+09:00
DateTime dt3 = new DateTime(2015, 7, 11, 15, 30, 0, 0);
DateTime dt4 = new DateTime(2015, 7, 13, 0, 0, 0, 0);
Interval interval2 = new Interval(dt3, dt4);
System.out.println(interval2.toString());
// ⇒ 2015-07-11T15:30:00.000+09:00/2015-07-13T00:00:00.000+09:00
if (interval1.overlaps(interval2)) {
Interval overlap = interval1.overlap(interval2);
System.out.println(overlap.toString());
// ⇒ 2015-07-11T15:30:00.000+09:00/2015-07-12T00:00:00.000+09:00
} else {
System.out.println("not overlaps");
}
after()/before()
after
,before
で2つの期間の前後関係を確認することができます。
DateTime dt1 = new DateTime(2015, 7, 8, 0, 0, 0, 0);
DateTime dt2 = new DateTime(2015, 7, 9, 0, 0, 0, 0);
Interval a = new Interval(dt1, dt2);
System.out.println(a.toString());
// ⇒ 2015-07-08T00:00:00.000+09:00/2015-07-09T00:00:00.000+09:00
DateTime dt3 = new DateTime(2015, 7, 6, 0, 0, 0, 0);
DateTime dt4 = new DateTime(2015, 7, 7, 0, 0, 0, 0);
Interval b = new Interval(dt3, dt4);
System.out.println(b.toString());
// ⇒ 2015-07-06T00:00:00.000+09:00/2015-07-07T00:00:00.000+09:00
DateTime dt5 = new DateTime(2015, 7, 10, 0, 0, 0, 0);
DateTime dt6 = new DateTime(2015, 7, 11, 0, 0, 0, 0);
Interval c = new Interval(dt5, dt6);
System.out.println(c.toString());
// ⇒ 2015-07-10T00:00:00.000+09:00/2015-07-11T00:00:00.000+09:00
if (a.isAfter(b)) {
System.out.println("a is after b");
// ⇒ a is after b
} else {
System.out.println("a is not after b");
}
if (a.isBefore(b)) {
System.out.println("a is before b");
} else {
System.out.println("a is not before b");
// ⇒ a is not before b
}
if (a.isAfter(c)) {
System.out.println("a is after c");
} else {
System.out.println("a is not after c");
// ⇒ a is not after c
}
if (a.isBefore(c)) {
System.out.println("a is before c");
// ⇒ a is before c
} else {
System.out.println("a is not before c");
}
[Class Interval] (http://www.joda.org/joda-time/apidocs/org/joda/time/Interval.html)
Duration
期間を操作することができます。
plus/minusを使用して期間を短縮、延長することができます。
このクラスは期間をミリ秒単位で数学的に表現します。このクラスのメソッドは、ミリ秒単位での表現を標準的な数学変換 (1 分は 60 秒、1 日は 24 時間など) によって秒、分、時などの標準単位での表現に変換するために使用することができます。
Duration のインスタンスを使用して期間を表現するのは、その特定の期間がいつから始まるかは重要でない場合、あるいは期間をミリ秒で処理すると都合がよい場合に限られます。
[Joda-Time - IBM developerWorks 日本語版] (http://www.ibm.com/developerworks/jp/java/library/j-jodatime.html)
DateTime dt5 = new DateTime(2015, 7, 1, 0, 0, 0);
DateTime dt6 = new DateTime(2016, 9, 4, 4, 5, 6);
Duration duration = new Duration(dt5, dt6);
System.out.println(String.format("Days:%d, Hours:%d, Minutes:%d, Seconds:%d",
duration.getStandardDays(),
duration.getStandardHours(),
duration.getStandardMinutes(),
duration.getStandardSeconds())
);
// ⇒ Days:431, Hours:10348, Minutes:620885, Seconds:37253106
System.out.println(PERIOD_FMT.print(duration.toPeriod()));
// ⇒ 0 years 0 months 0 weeks 0 days 10348 hours 5 minutes 6 seconds
System.out.println(PERIOD_FMT.print(duration.toPeriodFrom(dt5)));
// ⇒ 1 year 2 months 0 weeks 3 days 4 hours 5 minutes 6 seconds
/*1時間延長する*/
duration = duration.plus(1000L * 60L * 60L);
System.out.println(PERIOD_FMT.print(duration.toPeriodFrom(dt5)));
// ⇒ 1 year 2 months 0 weeks 3 days 5 hours 5 minutes 6 seconds
/*Partial*/
Days dDays = duration.toStandardDays();
Hours dHours = duration.toStandardHours();
Minutes dMinutes = duration.toStandardMinutes();
Seconds dSeconds = duration.toStandardSeconds();
System.out.println(String.format("Days:%d Hours:%d Minutes:%d Seconds:%d",
dDays.getDays(),
dHours.getHours(),
dMinutes.getMinutes(),
dSeconds.getSeconds()));
// ⇒ Days:431 Hours:10349 Minutes:620945 Seconds:37256706
[Class Duration] (http://www.joda.org/joda-time/apidocs/org/joda/time/Duration.html)
Period
期間を年や月、週や日といった単位で操作することが可能です。
このクラスが表現する概念は Duration と同じですが、その表現は、例えば年、月、週などといった「人間」にとっての観点からです。
Period を使用するのは、その期間がいつから始まるかが必ずしも重要でない場合や、あるいは Period によってカプセル化された期間を表す個々のフィールドを取得できるということが重要な場合です。
[Joda-Time - IBM developerWorks 日本語版] (http://www.ibm.com/developerworks/jp/java/library/j-jodatime.html)
DateTime dt7 = new DateTime(2015, 7, 1, 0, 0, 0);
DateTime dt8 = new DateTime(2016, 9, 4, 4, 5, 6);
Period period = new Period(dt7, dt8, PeriodType.yearMonthDayTime());
System.out.println(String.format("Years:%d, Months:%d, Days:%d, Hours:%d, Minutes:%d, Seconds:%d",
period.getYears(),
period.getMonths(),
period.getDays(),
period.getHours(),
period.getMinutes(),
period.getSeconds())
);
// ⇒ Years:1, Months:2, Days:3, Hours:4, Minutes:5, Seconds:6
System.out.println(PERIOD_FMT.print(period));
// ⇒ 1 year 2 months 0 weeks 3 days 4 hours 5 minutes 6 seconds
/*Partial*/
Years years = Years.yearsBetween(dt7, dt8);
Months months = Months.monthsBetween(dt7, dt8);
Days days = Days.daysBetween(dt7, dt8);
Hours hours = Hours.hoursBetween(dt7, dt8);
Minutes minutes = Minutes.minutesBetween(dt7, dt8);
Seconds seconds = Seconds.secondsBetween(dt7, dt8);
Weeks weeks = Weeks.weeksBetween(dt7, dt8);
System.out.println(String.format("Years:%d Months:%d Days:%d Hours:%d Minutes:%d Seconds:%d Weeks:%d",
years.getYears(),
months.getMonths(),
days.getDays(),
hours.getHours(),
minutes.getMinutes(),
seconds.getSeconds(),
weeks.getWeeks()));
// ⇒ Years:1 Months:14 Days:431 Hours:10348 Minutes:620885 Seconds:37253106 Weeks:61
[Class Period] (http://www.joda.org/joda-time/apidocs/org/joda/time/Period.html)
特定の日を求める
DateTime dt1 = DateTime.now();
System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-08(水) 午後22:34:17.159 +09:00.
/*年初、年末*/
DateTime yf = dt1.dayOfYear().withMinimumValue();
DateTime yl = dt1.dayOfYear().withMaximumValue();
System.out.println(DEF_FMT.print(yf));
// ⇒ 西暦 2015-01-01(木) 午後22:34:17.159 +09:00.
System.out.println(DEF_FMT.print(yl));
// ⇒ 西暦 2015-12-31(木) 午後22:34:17.159 +09:00.
/*月初、月末*/
DateTime mf = dt1.dayOfMonth().withMinimumValue();
DateTime ml = dt1.dayOfMonth().withMaximumValue();
System.out.println(DEF_FMT.print(mf));
// ⇒ 西暦 2015-07-01(水) 午後22:34:17.159 +09:00.
System.out.println(DEF_FMT.print(ml));
// ⇒ 西暦 2015-07-31(金) 午後22:34:17.159 +09:00.
/*週初、週末*/
DateTime wf = dt1.dayOfWeek().withMinimumValue();
DateTime wl = dt1.dayOfWeek().withMaximumValue();
System.out.println(DEF_FMT.print(wf));
// ⇒ 西暦 2015-07-06(月) 午後22:34:17.159 +09:00.
System.out.println(DEF_FMT.print(wl));
// ⇒ 西暦 2015-07-12(日) 午後22:34:17.159 +09:00.
/*今週の木曜日*/
DateTime dt2 = DateTime.now();
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2015-07-08(水) 午後22:34:17.160 +09:00.
dt2 = dt2.dayOfWeek().withMinimumValue().withDayOfWeek(DateTimeConstants.THURSDAY);
System.out.println(DEF_FMT.print(dt2));
// ⇒ 西暦 2015-07-09(木) 午後22:34:17.160 +09:00.
うるう年の判定
DateTime dt3 = new DateTime(2016, 2, 29, 0, 0, 0, 0);
System.out.println(DEF_FMT.print(dt3));
// ⇒ 西暦 2016-02-29(月) 午前00:00:00.000 +09:00.
if (dt3.year().isLeap()) {
System.out.println("うるう年");
// ⇒ うるう年
} else {
System.out.println("");
}
Instantを使った日付処理
Instant
は、Java epoch(1970-01-01 00:00:00.000)からのオフセットで日時の定点を表します。
インスタンスの生成やフォーマットの方法はDateTime
と似ています。
インスタンスの生成
コンストラクタ
Instant i1 = new Instant();
System.out.println(DEF_FMT.print(i1));
// ⇒ 西暦 2015-07-09(木) 午前00:36:16.368 +00:00.
引数に任意の時間のミリ秒を指定することもできます。
Instant i2 = new Instant(new Date().getTime());
System.out.println(DEF_FMT.print(i2));
// ⇒ 西暦 2015-07-09(木) 午前00:36:16.408 +00:00.
引数に0秒を指定するとepochになります。
Instant epoch = new Instant(0L);
System.out.println(DEF_FMT.print(epoch));
// ⇒ 西暦 1970-01-01(木) 午前00:00:00.000 +00:00.
now()
Instant i3 = Instant.now();
System.out.println(DEF_FMT.print(i3));
// ⇒ 西暦 2015-07-09(木) 午前00:36:16.408 +00:00.
parse()
Instant pi1 = Instant.parse("2006-01-02");
System.out.println(DEF_FMT.print(pi1));
// ⇒ 西暦 2006-01-01(日) 午後15:00:00.000 +00:00.
Instant pi2 = Instant.parse("2006-01-02T15:04:05");
System.out.println(DEF_FMT.print(pi1));
// ⇒ 西暦 2006-01-02(月) 午前06:04:05.000 +00:00.
Instant pi3 = Instant.parse("20060102 150405", DateTimeFormat.forPattern("yyyyMMdd HHmmss"));
System.out.println(DEF_FMT.print(pi1));
// ⇒ 西暦 2006-01-02(月) 午前06:04:05.000 +00:00.
タイムゾーンと暦
Instantはタイムゾーンを指定できません。デフォルトでUTC
が設定されています。
Instant i1 = Instant.now();
DateTimeZone defaultZone = i1.getZone();
Chronology defaultChro = i1.getChronology();
System.out.println(defaultZone.toString());
// ⇒ UTC
System.out.println(defaultChro.toString());
// ⇒ ISOChronology[UTC]
フォーマット
フォーマットはDateTime
と同じです。
Instant i1 = Instant.now();
System.out.println(DateTimeFormat.fullDateTime().print(i1));
// ⇒ 2015年7月9日 0時36分16秒 UTC
System.out.println(DateTimeFormat.longDateTime().print(i1));
// ⇒ 2015/07/09 0:36:16 UTC
System.out.println(DateTimeFormat.mediumDateTime().print(i1));
// ⇒ 2015/07/09 0:36:16
System.out.println(DateTimeFormat.shortDateTime().print(i1));
// ⇒ 15/07/09 0:36
日付の計算
Instant i1 = Instant.now();
System.out.println(shortFmt.print(i1));
// ⇒ 西暦 2015-07-09(木) 午前00:36:16.446 +00:00.
/*60秒加算*/
i1 = i1.plus(1000L * 60L);
System.out.println(shortFmt.print(i1));
// ⇒ 西暦 2015-07-09(木) 午前00:37:16.446 +00:00.
/*30秒減算*/
i1 = i1.minus(1000L * 30L);
System.out.println(shortFmt.print(i1));
// ⇒ 西暦 2015-07-09(木) 午前00:36:46.446 +00:00.
メモ
主要クラス
class | thread-safe | immutable | interface |
---|---|---|---|
Instant |
O | O | ReadableInstant |
Partial |
O | O | ReadablePartial |
BuddhistChronology |
O | O | |
CopticChronology |
O | O | |
EthiopicChronology |
O | O | |
GJChronology |
O | O | |
GregorianChronology |
O | O | |
IslamicChronology |
O | O | |
ISOChronology |
O | O | |
JulianChronology |
O | O | |
DateTime |
O | O |
ReadableDateTime ReadableInstant
|
LocalDateTime |
O | O | ReadablePartial |
LocalDate |
O | O | ReadablePartial |
LocalTime |
O | O | ReadablePartial |
YearMonth |
O | O | ReadablePartial |
MonthDay |
O | O | ReadablePartial |
Interval |
O | O | ReadableInterval |
Duration |
O | O | ReadableDuration |
Period |
O | O | ReadablePeriod |
Years |
O | O | ReadablePeriod |
Months |
O | O | ReadablePeriod |
Days |
O | O | ReadablePeriod |
Hours |
O | O | ReadablePeriod |
Minutes |
O | O | ReadablePeriod |
Seconds |
O | O | ReadablePeriod |
Weeks |
O | O | ReadablePeriod |