Posted at

Joda-Timeを使った日付処理まとめ

More than 3 years have passed since last update.


概要

Joda-Timeを使った日付処理のまとめです。

(なおJava8であればTime APIがあるのでJoda-Timeを使用する必要はありません)

環境

下記の環境で動作確認を行いました。


  • Windows7 (64bit)

  • Java 1.8.0_45


  • Joda-Time 2.8.1

参考

下記のサイトを参考にさせて頂きました。

Joda

blog

Stack Overflow

その他


DateTimeを使った日付処理

DateTimeはUTCからのオフセットやタイムゾーンを持つ日時を表すクラスです。似た名前のLocalDateTimeはUTCからのオフセットやタイムゾーンを持ちません。

サンプルコードの日付フォーマットについて

以降のサンプルコードで使用する日付フォーマットは下記の通りです。とくに断りが無い場合は日付をこのフォーマットで文字列にします。


datetime_formatter

DateTimeFormatter DEF_FMT = DateTimeFormat.forPattern("G yyyy-MM-dd(E) aHH:mm:ss.SSS ZZ.");


これも以降のサンプルコードで使用する期間用フォーマットです。


Period_formatter

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();


インスタンスの生成


コンストラクタ


constructor

DateTime dt1 = new DateTime();

System.out.println(DEF_FMT.print(dt1));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.897 +09:00.


constructor

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インスタンスを生成します。


now

DateTime dt5 = DateTime.now();

System.out.println(DEF_FMT.print(dt5));
// ⇒ 西暦 2015-07-08(水) 午後21:52:23.858 +09:00.


parse()

日付を表現する文字列を解析してDateTimeインスタンスを生成します。


parse

DateTime pd1 = DateTime.parse("2006-01-02");

System.out.println(DEF_FMT.print(pd1));
// ⇒ 西暦 2006-01-02(月) 午前00:00:00.000 +09:00.


parse

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.


parse

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インスタンス生成時に任意のタイムゾーンを指定することができます。

指定しない場合はデフォルトのタイムゾーンが使用されます。


timezone

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.


timezone

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.

デフォルトのタイムゾーン


timezone

DateTime dt1 = DateTime.now();

DateTimeZone defaultZone = dt1.getZone();
System.out.println(defaultZone);
// ⇒ Asia/Tokyo


DateTimeインスタンス生成時に任意の暦を指定することができます。


chronology

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.

デフォルトの暦


chronology

DateTime dt1 = DateTime.now();

Chronology defaultChrono = dt1.getChronology();
System.out.println(defaultChrono);
// ⇒ ISOChronology[Asia/Tokyo]


フォーマット

DateTimeインスタンスを指定した書式の文字列にフォーマットします。


事前定義フォーマット

DateTimeFormatクラスには事前定義されたフォーマットがあります。


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を使用する方法があります。


forPattern

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文字目に時刻のパターンを指定します。


forStyle

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を使用してフォーマットを組み立てることができます。


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系のメソッドを使って日時の加算を行います。


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系のメソッドを使って日時の減算を行います。


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系のメソッドを使って特定のフィールドの日時を変更します。


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系のメソッドを使って日付の丸め処理を行います。


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:002015-06-15 11:30:002015-07-15 11:30:00の日時に対して3種類の丸め処理を行った結果を下表にまとめました。


example

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:002015-06-16 11:30:002015-06-17 11:30:00の日時に対して3種類の丸め処理を行った結果を下表にまとめました。


example

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:002015-07-16 11:30:002015-07-17 11:30:00の日時に対して3種類の丸め処理を行った結果を下表にまとめました。


exmaple

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:002015-06-15 11:30:002015-06-15 11:31:00の日時に対して3種類の丸め処理を行った結果を下表にまとめました。


example

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


日付の比較


example

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 日本語版



abuts()

abutsで2つの期間が隣接しているか確認することができます。


abuts

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つの期間の隔たりを確認することができます。


gap

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つの期間の重なった範囲を確認することができます。


overlap

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


Duration

期間を操作することができます。

plus/minusを使用して期間を短縮、延長することができます。


このクラスは期間をミリ秒単位で数学的に表現します。このクラスのメソッドは、ミリ秒単位での表現を標準的な数学変換 (1 分は 60 秒、1 日は 24 時間など) によって秒、分、時などの標準単位での表現に変換するために使用することができます。

Duration のインスタンスを使用して期間を表現するのは、その特定の期間がいつから始まるかは重要でない場合、あるいは期間をミリ秒で処理すると都合がよい場合に限られます。

Joda-Time - IBM developerWorks 日本語版



Duration

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


Period

期間を年や月、週や日といった単位で操作することが可能です。


このクラスが表現する概念は Duration と同じですが、その表現は、例えば年、月、週などといった「人間」にとっての観点からです。

Period を使用するのは、その期間がいつから始まるかが必ずしも重要でない場合や、あるいは Period によってカプセル化された期間を表す個々のフィールドを取得できるということが重要な場合です。

Joda-Time - IBM developerWorks 日本語版



Period

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


特定の日を求める


example

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.


うるう年の判定


isLeap

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と似ています。


インスタンスの生成


コンストラクタ


constructor

Instant i1 = new Instant();

System.out.println(DEF_FMT.print(i1));
// ⇒ 西暦 2015-07-09(木) 午前00:36:16.368 +00:00.

引数に任意の時間のミリ秒を指定することもできます。


constructor

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になります。


constructor

Instant epoch = new Instant(0L);

System.out.println(DEF_FMT.print(epoch));
// ⇒ 西暦 1970-01-01(木) 午前00:00:00.000 +00:00.


now()


now

Instant i3 = Instant.now();

System.out.println(DEF_FMT.print(i3));
// ⇒ 西暦 2015-07-09(木) 午前00:36:16.408 +00:00.


parse()


parse

Instant pi1 = Instant.parse("2006-01-02");

System.out.println(DEF_FMT.print(pi1));
// ⇒ 西暦 2006-01-01(日) 午後15:00:00.000 +00:00.


parse

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.


parse

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が設定されています。


timezone

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と同じです。


format

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



日付の計算


example

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


Chronologyクラス

class
description

Chronology
抽象クラス

BuddhistChronology
仏暦

CopticChronology
コピト暦

EthiopicChronology
エチオピア暦

GJChronology
グレゴリオ/ユリウス暦?

GregorianChronology
グレゴリオ暦

IslamicChronology
イスラム暦

ISOChronology
based on the ISO-8601 standard.

JulianChronology
ユリウス暦