LoginSignup
79
76

More than 5 years have passed since last update.

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

Posted at

概要

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 ユリウス暦
79
76
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
79
76