こんにちは。初めまして。Androidエンジニアの斎藤です。 今回はJavaで日付/時刻などを扱うライブラリThreeTenをAndroidで利用するための基本的な導入方法、使用方法について紹介します。
ThreeTenABPって何?
Java8から導入されたDate and Time API(JSR-310)を参照実装したものをAndroidで利用可能なようにバックポートしたものです。 ABPはAndroid Backportの略です。バックポート人はJake Wharton大先生です。
導入方法
AndroidStudioのbuild.gradle
に下記を追加します。
compile 'com.jakewharton.threetenabp:threetenabp:1.0.3'
Application
を継承したクラスのonCreate()
メソッドで初期化します。
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); AndroidThreeTen.init(this); // <- } }
AndroidManifestにも忘れずに。
<application android:name=".MyApplication" <- android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
簡単な使用方法
LocalDate
LocalDate
は日付に関する情報を扱うクラスです。
// 今日の日付を取得する LocalDate todayDate = LocalDate.now(); Log.d(TAG, "todayDate: " + todayDate); // -> todayDate: 2016-06-24 // 今日の日付の年(Year)を取得する int year = todayDate.getYear(); Log.d(TAG, "todayDate: year " + year); // -> todayDate: year 2016 // 今日の日付の月(Month)を取得する int monthValue = todayDate.getMonthValue(); Log.d(TAG, "todayDate: monthValue " + monthValue); // -> todayDate: monthValue 6 // 今日の日付の日(Day)を取得する int dayOfMonth = todayDate.getDayOfMonth(); Log.d(TAG, "todayDate: dayOfMonth " + dayOfMonth); // -> todayDate: dayOfMonth 24 // 今日の日付の週(Week)を取得する String dayOfWeek = todayDate.getDayOfWeek().toString(); Log.d(TAG, "todayDate: dayOfWeek " + dayOfWeek); // -> todayDate: dayOfWeek FRIDAY
フォーマットも簡単。
// 表示を切り替えてみる DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日"); String formatted = todayDate.format(formatter); Log.d(TAG, "formatted: " + formatted); // -> formatted: 2016年06月24日
その他、日付の演算も直感的で簡単にできます。
// 1年前の日付を取得する LocalDate oneYearAgo = todayDate.minusYears(1L); Log.d(TAG, "oneYearAgo: " + oneYearAgo); // -> oneYearAgo: 2015-06-24 // 1年後の日付を取得する LocalDate oneYearLater = todayDate.plusYears(1L); Log.d(TAG, "oneYearLater: " + oneYearLater); // -> oneYearLater: 2017-06-24 // 1か月前の日付を取得する LocalDate oneMonthAgo = todayDate.minusMonths(1L); Log.d(TAG, "oneMonthAgo: " + oneMonthAgo); // -> oneMonthAgo: 2016-05-24 // 1か月後の日付を取得する LocalDate oneMonthLater = todayDate.plusMonths(1L); Log.d(TAG, "oneMonthLater: " + oneMonthLater); // -> oneMonthLater: 2016-07-24 // 1週間前の日付を取得する LocalDate oneWeekAgo = todayDate.minusWeeks(1L); Log.d(TAG, "oneWeekAgo: " + oneWeekAgo); // -> oneWeekAgo: 2016-06-17 // 1週間後の日付を取得する LocalDate oneWeekLater = todayDate.plusWeeks(1L); Log.d(TAG, "oneWeekLater: " + oneWeekLater); // -> oneWeekLater: 2016-07-01 // 1日前の日付を取得する LocalDate oneDayAgo = todayDate.minusDays(1L); Log.d(TAG, "oneDayAgo: " + oneDayAgo); // -> oneDayAgo: 2016-06-23 // 1日後の日付を取得する LocalDate oneDayLater = todayDate.plusDays(1L); Log.d(TAG, "oneDayLater: " + oneDayLater); // -> oneDayLater: 2016-06-25
LocalTime
LocalTime
は時刻に関する情報を扱うクラスです。
// 現在の時刻を取得する LocalTime localTime = LocalTime.now(); Log.d(TAG, "localTime: " + localTime); // -> localTime: 17:44:21.557 // 現在の時刻から時(Hour)を取得する int hour = localTime.getHour(); Log.d(TAG, "localTime: hour " + hour); // -> localTime: hour 17 // 現在の時刻から分(Minutes)を取得する int minute = localTime.getMinute(); Log.d(TAG, "localTime: minute " + minute); // -> localTime: minute 44 // 現在の時刻から秒(Second)を取得する int second = localTime.getSecond(); Log.d(TAG, "localTime: second " + second); // -> localTime: second 21 // 現在の時刻からナノ秒(Nano)を取得する int nano = localTime.getNano(); Log.d(TAG, "localTime: nano " + nano); // -> localTime: nano 557000000
フォーマットも。
// 表示を切り替える DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH時mm分ss.SSS秒"); String formatted = localTime.format(formatter); Log.d(TAG, "formatted: " + formatted); // -> formatted: 17時44分21.557秒
演算も。
// 1時間前の時刻を取得する LocalTime oneHourAgo = localTime.minusHours(1L); Log.d(TAG, "oneHourAgo: " + oneHourAgo); // 1時間前の時刻を取得する LocalTime oneHourLater = localTime.plusHours(1L); Log.d(TAG, "oneHourLater: " + oneHourLater); // 1分前の時刻を取得する LocalTime oneMinutesAgo = localTime.minusMinutes(1L); Log.d(TAG, "oneMinutesAgo: " + oneMinutesAgo); // 1分後の時刻を取得する LocalTime oneMinutesLater = localTime.plusMinutes(1L); Log.d(TAG, "oneMinutesLater: " + oneMinutesLater); // 1秒前の時刻を取得する LocalTime oneSecondsAgo = localTime.minusSeconds(1L); Log.d(TAG, "oneSecondsAgo: " + oneSecondsAgo); // 1秒後の時刻を取得する LocalTime oneSecondsLater = localTime.plusSeconds(1L); Log.d(TAG, "oneSecondsLater: " + oneSecondsLater); // 1ナノ秒後の時刻を取得する LocalTime oneNanosAgo = localTime.minusNanos(1L); Log.d(TAG, "oneNanosAgo: " + oneNanosAgo); // 1ナノ後の時刻を取得する LocalTime oneNanosLater = localTime.plusNanos(1L); Log.d(TAG, "oneNanosLater: " + oneNanosLater);
LocalDateTime
LocalDateTime
は日付と時刻に関する情報を扱うクラスです。
// 現在の日付と時刻を取得する LocalDateTime localDateTime = LocalDateTime.now(); Log.d(TAG, "localDateTime: " + localDateTime); // -> localDateTime: 2016-06-24T17:44:21.563
上記2つで紹介したメソッドももちろん利用可能です。 加えて日付と時刻両方に関する演算も可能です。
// 1年と1時間前の日付と時刻を取得する LocalDateTime oneYearAndHourAgo = localDateTime.minusYears(1L).minusHours(1L); Log.d(TAG, "oneYearAndHourAgo: " + oneYearAndHourAgo); // -> oneYearAndHourAgo: 2015-06-24T16:44:21.563 // 1年と1時間後の日付と時刻を取得する LocalDateTime oneYearAndHourLater = localDateTime.plusYears(1L).plusHours(1L); Log.d(TAG, "oneYearAndHourLater: " + oneYearAndHourLater); // -> oneYearAndHourLater: 2017-06-24T18:44:21.563
比較も簡単です。
// 指定した日時の差分を取得する LocalDateTime from = LocalDateTime.of(2016, 6, 24, 16, 30, 30); LocalDateTime to = LocalDateTime.now(); Duration duration = Duration.between(from, to); long durationHours = duration.toHours(); Log.d(TAG, "durationHours: " + durationHours); // -> durationHours: 3
ZonedDateTime
ZonedDateTime
は日付と時刻に関する情報を扱うクラスです。
LocalDateTime
との違いはタイムゾーンがつきます。
// 現在の日付と時刻を取得する ZonedDateTime zonedDateTime = ZonedDateTime.now(); Log.d(TAG, "zonedDateTime: " + zonedDateTime); // -> zonedDateTime: 2016-06-24T17:44:21.565+09:00[Asia/Tokyo]
おわりに
今回は簡単な使い方のみの紹介でしたが従来のDate, Calenderに比べてだいぶ使いやすくなったなぁという印象です。 積極的に利用してきたいと思いました。また、本記事を書くにあたり参考にした記事を後術しますが、中でも参考になったのが下記です。 http://builder.japan.zdnet.com/sp_oracle/weblogic/35067620/ なぜ、JSR-310が必要になったかから始まり、次の給料日を求めるなど実用的(?)なサンプルもあり為になりました。ぜひ読んでみてください。
今回作成したサンプルプロジェクトはGithubリポジトリへあげてあります。
参考にしたもの
[ThreeTenABP]
https://github.com/JakeWharton/ThreeTenABP
[日本人のためのDate and Time API Tips]
http://www.coppermine.jp/docs/programming/2013/12/jsr310-tips.html
[JavaDoc]
http://docs.oracle.com/javase/8/docs/api/
[必修! Date and Time API──Java SE 8の新日時APIの基本を学ぶ]
http://builder.japan.zdnet.com/sp_oracle/weblogic/35067620/
[今日から始めるJava8]
http://acro-engineer.hatenablog.com/entries/2013/02/06
[Androidで使える日付処理系のライブラリーを試してみた]
http://qiita.com/futabooo/items/206b71ee8022ac685ece
[日付操作(JSR-310 Date and Time API)]
[旧日時APIとの相互変換&Java 6/7でDate-Time APIが使えるライブラリThreeTen Backport (1/3)]
http://www.atmarkit.co.jp/ait/articles/1504/02/news144.html
[Java 8日時APIの主なメソッドとフォーマット用のパターン文字の使い方 (1/6)]
http://www.atmarkit.co.jp/ait/articles/1501/29/news016.html
子育て家族アプリFamm、カップル専用アプリPairyを運営する Timers inc. では、現在エンジニアを積極採用中!急成長中のサービスの技術の話を少しでも聞いてみたい方、スタートアップで働きたい方など、是非お気軽にご連絡ください!
採用HP : http://timers-inc.com/engineerings