読者です 読者をやめる 読者になる 読者になる

Webサービスで起業を目指すプログラマーblog

仕事で使ったプログラミング、サーバー周りで役に立つこと、Webサービス開発に必要な技術情報、モバイル情報を書いてます。わかりやすく見やすくをモットーにしています。

Javaで面倒くさい日付の扱いを簡単にするライブラリ「Joda-Time」 日付編

Java JodaTime

Javaで日付を扱うときDateやCalendarを使います。
これらのクラスを使うとき、結構手順を踏まないと目的の日付を取得出来ません。
コードも長くなってメンテナンスもしにくくなります。


そんな問題を解決したのが、日付に特化した「Joda-Time」ライブラリです。


よく使うもので大きく分けると「日付」と「期間」という2つの括りになります。
内容が長くなるのでこの2つで分けて記事にしました。


期間編はこちらです。shinsuke789.hatenablog.jp


日本語のドキュメントがあまりなかったので、時間をかけてまとめてみました。


まとめてみて感じたのが、結構簡単に日付を扱えるということ、作成した日付に対して連続で違う処理を行えることがかなりいいと感じました。
ただ、柔軟すぎてどのメソッドを使ったらいいか迷いますので、ここでは簡潔に書けて必要なものだけ上げました。

Joda-Timeとは?

Javaの日付関連のクラスを扱いやすくしたOSSライブラリです。

Calendarクラスでは、0から始まっていた月、週は1から始まります。

公式サイトはこちらです。

必要なライブラリ

joda-time-xxx.jar

今回はバージョン2.2でまとめています。

Jodaの日付クラス

クラス名 機能
DateTime JavaのCalendarにあたるクラス
DateTimeMidnight DateTimeの時間を00:00:00.000に固定したクラス
LocalDate ロケールを含まず、日付のみを扱うクラス
LoclTime ロケールを含まず、時間のみ扱うクラス
LocalDateTime ロケールを含まず、日付と時間を扱うクラス

サンプルコードではDateTimeを使用していますが、上記クラスでも定義可能です。

使い方

DateTimeの初期化
// 引数なし
DateTime dt = new DateTime();

// Date型から
DateTime dt = new DateTime(new Date());

// Calendar型から
DateTime dt = new DateTime(Calendar.getInstance());

// ISO日付文字列から
DateTime dt = new DateTime("2013-08-01");
DateTime dt = new DateTime("2013-08-01T12:30:50")

// 年月日時分
DateTime dt = new DateTime(2013, 8, 1, 12, 30);

// 年月日時分秒
DateTime dt = new DateTime(2013, 8, 1, 12, 30, 50);

// ミリ秒から
Date d = new Date();
DateTime dt = new DateTime(d.getTime());
DateTimeからの変換
DateTime dt = new DateTime();

// Calendarに変換
Calendar calendar = dt.toCalendar(null);

// Dateに変換
Date date = dt.toDate();

// DateMidnightに変換
DateMidnight dateMidnight = dt.toDateMidnight();

// LocalDateに変換
LocalData localDate = dt.toLocalDate();

// LocalDateTimeに変換
LocalDateTime localDateTime = dt.toLocalDateTime();

// LocalTimeに変換
LocalTime localTime = dt.toLocalTime();
日付の取得
Calendarクラスのgetに相当し、結果を数値で取得する。
// 現在日付取得
// 2013-08-01T12:30:50.666+09:00
DateTime dt = new DateTime();

// 年 => 2013
dt.getYear();

// 月 => 8
dt.getMonthOfYear();

// 日 => 1
dt.getDayOfMonth();

// 曜日(月曜日=1、日曜日=7)=> 4
dt.getDayOfWeek();

// 時 => 12
dt.getHourOfDay();

// 分 => 30
dt.getMinuteOfHour();

// 秒 => 50
dt.getSecondOfMinute();

// ミリ秒 => 666
dt.getMillisOfSecond();

// 1970/1/1からのミリ秒 => 1375327850666
dt.getMillis();

// 月末 => 31(8月の末日)
dt.dayOfMonth().getMaximumValue();

// 通年日 => 213
dt.getDayOfYear();

// 通年週 => 31
dt.getWeekOfWeekyear();
日付の再設定

Calendarクラスのsetメソッドに相当し、結果をDateTimeやLocalDateなどのクラスで取得する。

DateTime dt = new DateTime();

// 日付
dt.withDate(2013, 10, 20);

// 時刻
dt.withTime(12, 30, 50, 333);

// 年
dt.withYear(2012);

// 月
dt.withMonthOfYear(5);

// 日
dt.withDayOfMonth(10);

// 曜日(月曜日=1、日曜日=7)
dt.withDayOfWeek(3);

// 時
dt.withHourOfDay(12);

// 分
dt.withMinuteOfHour(30);

// 秒
dt.withSecondOfMinute(50);

// ミリ秒
dt.withMillisOfSecond(321);

// 1970/1/1からのミリ秒
dt.withMillis(1324543605407);

// 通年日
dt.withDayOfYear(34);

// 通年週
dt.withWeekOfWeekYear(10);
日付のフォーマット
// 2013-08-01T12:30:50.666+09:00
DateTime dt = new DateTime();

// --- 文字列
// 全て => 2013-08-01T12:30:50.666+09:00
dt.toString();

// 年のみ => 2013
dt.toString("yyyy");

// 月のみ => 08
dt.toString("MM");

// 日のみ => 01
dt.toString("dd");

// 時のみ => 12
dt.toString("HH");

// 分のみ => 30
dt.toString("mm");

// 秒のみ => 50
dt.toString("ss");

// ミリ秒のみ => 666
dt.toString("SSS");

// --- 年月日、時分秒フォーマット
// => 2013年8月1日
dt.toString(DateTimeFormat.fullDate());
// => 2013年8月1日 12時30分50秒 JST
dt.toString(DateTimeFormat.fullDateTime());
// => 12時30分50秒 JST
dt.toString(DateTimeFormat.fullTime());

// --- 「/」「:」フォーマット
// => 2013/08/01
dt.toString(DateTimeFormat.longDate());
// => 2013/08/01 12:30:50 JST
dt.toString(DateTimeFormat.longDateTime());
// => 12:30:50 JST
dt.toString(DateTimeFormat.longTime());

// --- JSTを省略
// => 2013/08/01
dt.toString(DateTimeFormat.mediumDate());
// => 2013/08/01 12:30:50
dt.toString(DateTimeFormat.mediumDateTime());
// => 12:30:50
dt.toString(DateTimeFormat.mediumTime());

// --- 年を2桁または秒を省略
// => 13/08/01
dt.toString(DateTimeFormat.shortDate());
// => 13/08/01 12:30
dt.toString(DateTimeFormat.shortDateTime());
// => 12:30
dt.toString(DateTimeFormat.shortTime());
日付文字列の変換
// --- 文字列からDateTime型へ変換
// yyyy/MM/dd
DateTimeFormat.forPattern("yyyy/MM/dd").parseDateTime("2013/08/01");

// スラッシュなし
DateTimeFormat.forPattern("yyyyMMdd").parseDateTime("20130801");

// 日時スラッシュなし(CSVなどの文字列でよくあるパターン)
DateTimeFormat.forPattern("yyyyMMddHHmmss").parseDateTime("20130801102030");

// --- 文字列からLocalDate型へ変換
DateTimeFormat.forPattern("yyyy/MM/dd").parseLocalDate("2013/08/01");

// --- 文字列からLocalDateTime型へ変換
DateTimeFormat.forPattern("yyyy/MM/dd").parseLocalDateTime("2013/08/01");

// --- 文字列からLocalTime型へ変換
DateTimeFormat.forPattern("HH:mm:ss").parseLocalTime("2013/08/01");

// --- 文字列からDateTime型に変換し、Date型にする
DateTimeFormat.forPattern("yyyy/MM/dd").parseDateTime("2013/08/01").toDate();

// --- 文字列からDateTime型に変換し、Calendar型にする
DateTimeFormat.forPattern("yyyy/MM/dd").parseDateTime("2013/08/01").toCalendar(Locale.JAPANESE);
日付の比較
// 2013-01-01 00:00:00
DateTime dt1 = new DateTime(2013, 1, 1);
// 2013-02-01 00:00:00
DateTime dt2 = new DateTime(2013, 2, 1);

// --- 2つのDateTime日時との比較
// dt1はdt2より未来か? => false
dt1.isAfter(dt2);

// dt1はdt2より過去か? => true
dt1.isBefore(dt2);

// dt1とdt2は等しいか? => false
dt1.isEqual(dt2);

// --- 現在日時との比較
// 現在 => 2013-03-01 00:00:00のとき
// dt1は現在日時より未来か? => false
dt1.isAfterNow();

// dt1は現在日時より過去か? => true
dt1.isBeforeNow();

// dt1と現在日時は等しいか? => false
dt1.isEqualNow();
日付の加算

設定した値のDateTimeが返ってくるので、再度DateTimeを宣言してから取得する必要があります。

// // 2013-08-01T12:30:50.666+09:00
DateTime dt = new DateTime();

// 月加算 => 2013-10-01T12:30:50.666+09:00
DateTime dt = dt.plusMonths(2);

// 日加算 => 2013-08-11T12:30:50.666+09:00
DateTime dt = dt.plusDays(10);

// 時加算 => 2013-08-01T16:30:50.666+09:00
DateTime dt = dt.plusHours(4);

// 分加算 => 2013-08-01T12:50:50.666+09:00
DateTime dt = dt.plusMinutes(20);

// 秒加算 => 2013-08-01T12:31:20.666+09:00
DateTime dt = dt.plusSeconds(30);

// ミリ秒加算 => 2013-08-01T12:30:51.166+09:00
DateTime dt = dt.plusMillis(500);
日付の減算

日付の加算と同様に、戻ってきたDateTimeより反映された新しい値を取得します。

DateTime dt = new DateTime();

// 月減算 => 2013-06-01T12:30:50.666+09:00
DateTime dt = dt.minusMonths(2);

// 日減算 => 2013-07-22T12:30:50.666+09:00
DateTime dt = dt.minusDays(10);

// 時減算 => 2013-08-01T08:30:50.666+09:00
DateTime dt = dt.minusHours(4);

// 分減算 => 2013-08-01T12:10:50.666+09:00
DateTime dt = dt.minusMinutes(20);

// 秒減算 => 2013-08-01T12:30:20.666+09:00
DateTime dt = dt.minusSeconds(30);

// ミリ秒減算 => 2013-08-01T12:30:50.166+09:00
DateTime dt = dt.minusMillis(500);
日付の差分
DateTime dt1 = new DateTime(2013, 5, 10, 20, 40, 30);
DateTime dt2 = new DateTime(2015, 7, 1, 12, 30, 10);

// 年 => 2
int year = Years.yearsBetween(dt1, dt2).getYears();

// 月 => 25
int month = Months.monthsBetween(dt1, dt2).getMonths();

// 日 => 781
int day = Days.daysBetween(dt1, dt2).getDays();

// 時 => 18759
int hour = Hours.hoursBetween(dt1, dt2).getHours();

// 分 => 1125589
int minute = Minutes.minutesBetween(dt1, dt2).getMinutes();

// 秒 => 67535380
int second = Seconds.secondsBetween(dt1, dt2).getSeconds();
システム日付
// 現在日時を取得する
DateTimeUtils.currentTimeMillis() 

// 現在日時を指定のミリ秒で強制的に変更する
DateTimeUtils.setCurrentMillisFixed(millis);

// 現在日時を現在の時刻からのミリ秒オフセットで強制的に変更する
DateTimeUtils.setCurrentMillisOffset(millis);

// 強制変更した現在日時をリセットする
DateTimeUtils.setCurrentMillisSystem();
定数

DateTimeConstantsが定数クラス。

// --- 曜日
// 月曜(1)
DateTimeConstants.MONDAY
// 火曜(2)
DateTimeConstants.TUESDAY
// 水曜(3)
DateTimeConstants.WEDNESDAY
// 木曜(4)
DateTimeConstants.THURSDAY
// 金曜(5)
DateTimeConstants.FRIDAY
// 土曜(6)
DateTimeConstants.SATURDAY
// 日曜(7)
DateTimeConstants.SUNDAY

// --- 月
// 1月
DateTimeConstants.JANUARY
// 2月
DateTimeConstants.FEBRUARY
// 3月
DateTimeConstants.MARCH
// 4月
DateTimeConstants.APRIL
// 5月
DateTimeConstants.MAY
// 6月
DateTimeConstants.JUNE
// 7月
DateTimeConstants.JULY
// 8月
DateTimeConstants.AUGUST
// 9月
DateTimeConstants.SEPTEMBER
// 10月
DateTimeConstants.OCTOBER
// 11月
DateTimeConstants.NOVEMBER
// 12月
DateTimeConstants.DECEMBER


Javaライブラリの解説を含む本

現場で使えるJavaライブラリ

現場で使えるJavaライブラリ