Your SlideShare is downloading. ×
Introduction to Date and Time API, 2nd edition
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Introduction to Date and Time API, 2nd edition

1,853

Published on

Introduction to Date and Time API, 2nd edition #jjug #ccc_r21

Introduction to Date and Time API, 2nd edition #jjug #ccc_r21

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,853
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
25
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Introduction to Date and Time API II November 9, 2013 #ccc_r21 HASUNUMA Kenji GlassFish Community khasunuma@java.net Twitter: @khasunuma
  • 2. Time?
  • 3. Representation of Date/Time
  • 4. ANSI/ISO Cのtime_tと機能的に同等 java.util.Date 現在は日付・時刻の表現のみに徹する ※java.sql.Date等のサブクラス Javaの国際化対応(JDK 1.1)で導入 java.util.Calendar 日付・時刻の作成・編集に用いる ※GregorianCalendar等のサブクラス java.time.* (JSR 310) JDK8~、Date/Calendar代替が当初の目標 日付・時刻を総合的に扱うフレームワーク ※規模はJDK8の新APIでも最大級 ※その他、XML DOM APIのXMLGregorianCalendarがある
  • 5. java.util.Dateの課題 • フィールド操作が面倒 • 年フィールド+1900が実際の年 • 月が0から始まる (1月→0…12月→11) • フィールドの直接操作が非推奨 (Calendarを使う) • 日付部と時刻部が混在している • 日付演算が貧弱、フォーマット機能も使い勝手に難 • JDK 1.1以降、一部例外を除きメンテナンスなし
  • 6. java.util.Calendarの課題 • フィールド操作が面倒 (Dateよりは改善) • 月が0から始まる →定数でお茶を濁す • フィールド操作の使い勝手がイマイチ • 日付演算が貧弱 … それでもDateよりは多少マシ • 日付・時刻型として認識されないことも多い
 例: DateFormat → Dateとの相互変換を利用
  • 7. java.util.Calendarの改善 JDK8よりCalendar.Builderを導入 →メソッドチェーン(1行)で日付・時刻を表せる // 2013年11月9日を表すCalendar (since JDK8) Calendar calendar = new Calendar.Builder() .setDate(2013, NOVEMBER, 9) .setField(HOUR_OF_DAY, 9) .build();
  • 8. JSR 310 Date and Time API
  • 9. JSR 310 : Date and Time API • Date、Calendar、DateFormat等を置き 換えることが目的 • ISO 8601形式の日付・時刻表現 • ImmutableかつスレッドセーフなAPI • 設計思想はJoda-Timeに酷似
  • 10. java.util.Date JSR 310 オブジェクト Mutable Immutable 精度 ミリ秒 ナノ秒 フィールド操作 Calendar経由 直接サポート タイムゾーン サポート サポート toString戻り値 Unix形式 ISO 8601形式 日付と時刻の分離 不可 可能 日付演算 比較のみ 様々な日付演算 関連クラス数 数個 たくさん
  • 11. JSR 310のメリット • 月:1∼12 (Date, Calendarは0∼11) • toStringでISO 8601形式を返す • 日付と時刻を分離することができる • 多様な日付演算機能を持つ • スレッドセーフである
  • 12. JSR 310のデメリット • JDK8 APIの中でも最大規模(=複雑) • 既存APIとの相互運用性はガン無視 • Dateとの相互変換は比較的最近に実現 • 今後の展開が不明瞭 • JPAやJAXBへの展開は検討中? • 少なくともJavaFX 8には間に合わず
  • 13. 参考: ISO 8601形式 • 日付: yyyy-MM-dd • 2013-11-09 • 時刻: hh:mm:ss.SSSZ • 04:05:00.000Z • 日時: yyyy-MM-dd’T’HH:mm:ss.SSSZ • 2013-11-09T04:05:00.000Z
  • 14. JSR 310 Essentials
  • 15. マシン向けの表現(内部表現) • Instant • Duration • Clock 人間向けの表現(外部表現) • DateTime • Period • Chronology
  • 16. マシン向けの表現(内部表現)
  • 17. 人間向けの表現(外部表現)
  • 18. DateTime : 日付・時刻 • TemporalAccessor等の実装 • 現在日時または任意の日時から生成 • DateTimeの演算(plus/minus)および他 のDateTimeからの変換をサポート • Instantに対応する人間向け表現
  • 19. 主なDateTimeの実装 • LocalDate, LocalTime, LocalDateTime • OffsetTime, OffsetDateTime • ZonedDateTime • 不足情報の追加または余剰情報の切り 捨てにより相互に変換可
  • 20. Date DateTime 年/月/日 Local Time ! ! 時/分/秒/未満 時差情報なし 年/月/日 時/分/秒/未満 時差情報なし 時差情報なし 年/月/日 時/分/秒/未満 時/分/秒/未満 UTCからの時差 UTCからの時差 ! Offset Zoned N/A N/A N/A 年/月/日 時/分/秒/未満 タイムゾーン
  • 21. OffsetDateTime vs. ZonedDateTime • OffsetDateTime - UTCからの時差のみ考慮 • ZonedDateTime - タイムゾーンを考慮 ※タイムゾーン UTCからの時差 タイムゾーンは以下も考慮している: • 夏時間(米国や西欧で多く導入) • 時差の改訂(ごく稀に発生)
  • 22. Chronology : 暦 Chronology ChronoLocalDate (インタフェース) 暦そのものを表し、各種変換 メソッドを提供 暦の情報を含むLocalDate ChronoLocalDateTime
 ChronoLocalDateに
 <D extends ChronoLocalDate> 時刻を付加 ChronoZonedDateTime
 ChronoLocalDateに
 <D extends ChronoLocalDate> 時刻とタイムゾーンを付加 Era 暦の紀元(開始年)を表す ※和暦は開始・終了年月日
  • 23. Chronologyの実装クラス IsoChronology/-Era LocalDate ISO 8601(標準) JapaneseChronology/-Era JapaneseDate 和暦(日本) ThaiBuddistChronology/-Era ThaiBuddistDate 仏暦(タイ) MinguoChronology/-Era MinguoDate 民国紀元(台湾) HijirahChronology/-Era HijirahDate イスラム暦
  • 24. 日付・時刻演算 • DateTime、Period、Instant、Durationはそれ自身が 加算・減算・比較・判定・変換メソッドを持つ • OpenJDK合流以前と比較して機能は大幅に削減さ れたものの、依然としてDate/Calendarより強力 • 昨年同時期と比較して、Chronologyの使い勝手は向 上した模様 (インタフェースのdefaultメソッド乱用という悪しき前例を作ったが…) • Immutableのため、演算結果がもとのオブジェクト に影響しないのも大きなメリット
  • 25. 日付・時刻の構成要素 Year Month 「年」を表すクラス ※加減算・判定・各種変換メソッド 「月」を表す列挙型、月末日付も保持 ※加減算・各種変換メソッド YearMonth 「年月」を表すクラス ※加減算・判定・各種判定メソッド MonthDay 「月日」を表すクラス ※「年」を加えればLocalDateへ DayOfWeek 「曜日」を表す列挙型 ※DateTimeからの曜日取得も可
  • 26. JSR 310のフォーマット機能 • LocalDate等のtoStringメソッドは、ISO 8601形式 でフォーマットしたものを返す • 標準以外のフォーマット→DateTimeFormatter
 ※DateTimeFormatterには使用頻度の高いフォーマットが定義済み • フォーマットを新しく作成する場合は、 DateTimeFomatterBuilderの使用を推奨
 ※国内ではyyyy/MM/dd形式が普及しているため、欧米と比較して DateTimeFormatterBuilderの使用頻度は高いと思われる • java.text.DateFormatはJSR 310では使用できない
 ※逆にDateTimeFormatterはjava.text.DateFormatに変換可能
  • 27. Interoperability
  • 28. JSR 310 Date/Calendar変換 重要 : JSR 310はDate/Calendarとの直接変換を サポートしない • DateはInstantを介してJSR 310と相互変換が可能
 具体的にはDate.from() / Date.toInstant()を用いる • CalendarはCalendar.toInstant()でInstantに変換可能、 ただしその逆はできない • Instant.toEpochMilli() / Instant.ofEpochMilli() で Instantをlong値に変換する方法もあり
  • 29. ThreeTen backport • JSR 310からJDK8依存の部分を取り除き、JDK7で 利用可能にした、JSR 310ライクなライブラリ 
 (パッケージ名はjava.timeではなくorg.threeten.bp) • Java SE 8リリース前にJSR 310を予習するための 教材として最適 • Apache License 2.0のOSSとして配布
 https://github.com/ThreeTen/threetenbp
  • 30. Examples
  • 31. // 今日の日付を取得→date LocalDate date = LocalDate.now();
  • 32. // 2013年11月9日→date LocalDate date = 
 LocalDate.of(2013, 11, 9);
  • 33. // 今日の日付→d1 // 3日後の日付→d2 LocalDate d1 = LocalDate.now(); LocalDate d2 = d1.plusDays(3);
  • 34. // 今日の日付→date // 今日の13時40分→dateTime LocalDate date = LocalDate.now(); LocalDateTime dateTime = 
 date.atTime(13, 40);
  • 35. // 今日の日時→dateTime // 今日の日付→date LocalDateTime dateTime = 
 LocalDateTime.now(); LocalDate date =
 LocalDate.from(dateTime);
  • 36. // date: 1992年10月8日 (うるう年) // → leap = true LocalDate date = LocalDate.of(1992, 10, 8); boolean leap = date.isLeapYear();
  • 37. // 今日の日付→date // dateを標準出力へ LocalDate date = LocalDate.now(); System.out.println(date.toString()); 出力結果 2013-11-09
  • 38. // 今日の日付(和暦)→jdate // ThreeTen Backportでも結果自体は同じ JapaneseDate jdate =
 JapaneseDate.now(); System.out.println(jdate.toString); 出力結果 H25-11-09
  • 39. 応用 : JSR 310をJAXBに対応させてみる public class LocalDateXmlAdapter extends!         XmlAdapter<XMLGregorianCalendar, LocalDate> {! !     @Override!     public LocalDate unmarshal(XMLGregorianCalendar value) throws Exception {!         int timezone = value.getTimezone();!         ZoneOffset offset = ZoneOffset.ofTotalSeconds(timezone * 60);!         return OffsetDateTime.of(value.getYear(), value.getMonth(),!                 value.getDay(), 0, 0, 0, 0, offset).toLocalDate();!     }! !     @Override!     public XMLGregorianCalendar marshal(LocalDate value) throws Exception {!         ZoneOffset offset = OffsetDateTime.now().getOffset();!         int timezone = offset.getTotalSeconds() / 60;!         return DatatypeFactory.newInstance().newXMLGregorianCalendarDate(!                 value.getYear(), value.getMonthValue(), value.getDayOfMonth(),!                 timezone);!     }! ! }
  • 40. Conclusion
  • 41. JSR 310とは何なのか? • JSR 310はjava.util.Dateの欠点をすべて 解決しようとする野心的試み • 過去との互換性を断ち切ることで、日 付・時刻APIの理想を追求した • 正直やり過ぎ感も否めないが、既存API の問題点の多くを解決した点は評価
  • 42. Date/Calendarの今後は? • JSR 310が浸透するまで、当分の間はそ の位置づけに変化はないはず。 • Calendar.Builderは延命措置だが、短期 的には効果大。 • 日付の操作ではJSR 310に遠く及ばな いため、長期的にはフェードアウト?
  • 43. JDK8時代の日付・時刻表現 • お好きなAPIをどうぞ。 • Date/CalendarとJSR 310の相互変換につい ては早いうちに準備するのがベター。 • 当初からJSR 310の使える箇所は、業務ロ ジックの日付処理、JAXBおよびそれに依存 するJAX-RS/JAX-WS。
  • 44. Introduction to Date and Time API II HASUNUMA Kenji khasunuma@java.net Twitter: @khasunuma

×