Upload
kenji-hasunuma
View
3.223
Download
10
Embed Size (px)
DESCRIPTION
JJUG CCC 2012 Fall 「JSR 310 "Date and Time API" への招待」発表資料 (2012-11-20 奥付のスペルミス訂正)
Citation preview
Introduction to Date and Time API
HASUNUMA KenjiVice president, GlassFish Users Group Japan
[email protected]: @btnrouge
November 10, 2012
Javaにおける日付・時刻の扱い
JDK 1.1 以降、本質的には変化なし
java.util.Date (JDK 1.0)
• ANSI/ISO Cと機能的に同等
• UTC or ローカルタイムゾーン
•年/月/日/時/分/秒を取得・設定可
•日付と時刻を同じクラスで表す
java.util.Date (JDK 1.1)
•国際化対応…実装をCalendarベースに置き換え
•年/月/日/時/分/秒を操作するメソッドはすべて非推奨→Calendarで代替
•日付操作はCalendarに移行、Dateは日時を指し示すだけ
java.util.Dateの課題
•フィールド操作が面倒•年フィールド+1900が実際の年
•月が0から始まる(1月→0、12月→11)
• 日付部と時刻部が混在している
•日付演算とフォーマット機能が貧弱
JSR 310Date and Time API
Michael Nascimento Santos
Stephen Colebourne
Roger Riggs
JSR 310 : Date and Time API
• Date、Calendar、DateFormat等を置き換えることが目的
• ISO 8601形式の日付・時刻表現
• ImmutableかつスレッドセーフなAPI
•設計思想はJoda-Timeに酷似
Joda-Time JSR 310
Second System Syndrome
More simply
JSR 310 : Date and Time API2007年2月 - JSR 310承認、EG発足
2008年5月 - JavaOne 2008で発表
2010年3月 - Early Draft Review (1回目)
2012年10月 - Early Draft Review (2回目)
2013年10月? - Java SE 8リリース
java.util.Date JSR 310
オブジェクト Mutable Immutable
精度 ミリ秒 ナノ秒
フィールドR/W Calendar経由 直接サポート
タイムゾーン サポート サポート
toString戻り値 Unix形式 ISO 8601形式
日付と時刻の分離 不可 可能
日付演算 比較のみ 様々な日付演算
関連クラス数 数個 たくさん
メリット
•月:1~12 (Date, Calendarは0~11)
• toStringでISO 8601形式を返す
•日付と時刻を分離することができる
•多様な日付演算機能を持つ
•スレッドセーフである
デメリット
•サイズが大きい (クラス数が多い)→ Java SE APIの中でも最大級
•既存APIとの互換性に乏しい
•今後の展開(JPAやJAXBへの対応)が不明瞭
• Early Draft Review後も頻繁な仕様変更
参考: ISO 8601形式
•日付: yyyy-MM-dd
• 2012-11-10
•時刻: hh:mm:ss.SSSZ
• 07:30:00.000Z
•日時: yyyy-MM-dd’T’HH:mm:ss.SSSZ
• 2012-11-10T07:30:00.000Z
JSR 310 Essentials
マシン向けの表現(内部表現)• Instant• Duration• Clock
人間向けの表現(外部表現)• DateTime• Period• Chronology
Instant
Duration
Clock
DateTime : 日付・時刻クラス
• DateTimeインタフェースの実装
• 現在日時または任意の日時から生成
• DateTimeの演算(plus/minus)および他のDateTimeからの変換をサポート
• Instantに対応する人間向け表現
DateTimeインタフェースの実装
• LocalDate, LocalTime, LocalDateTime
• OffsetDate, OffsetTime, OffsetDateTime
• ZonedDateTime
• 不足情報の追加または余剰情報の切り捨てにより相互に変換可
Date Time DateTime
Local
Offset
Zoned
年/月/日
時差情報なし時/分/秒/未満時差情報なし
年/月/日時/分/秒/未満時差情報なし
年/月/日
UTCからの時差時/分/秒/未満UTCからの時差
年/月/日時/分/秒/未満UTCからの時差
N/A N/A年/月/日
時/分/秒/未満タイムゾーン
OffsetDateTime vs. ZonedDateTime
• OffsetDateTime - UTCからの時差
• ZonedDateTime - 実際のタイムゾーン
※タイムゾーンによっては時差が変動する
•夏時間 - 導入国では毎年発生
•タイムゾーンの時差の変更
Period : 期間クラス
•期間を表す (例: 3ヶ月と4日と7時間)
•フィールド直接指定、2つのDateTime、Durationから生成
•フィールド取得、Periodのplus/minus、Durationへの変換などをサポート
• Durationに対応する人間向け表現
Chronology : 暦クラス
• Chronologyクラス:暦の情報を保持、ChronoDateを生成
• ChronoDateクラス:DateTimeをラップして各々の暦に変換※最新の実装では複数クラスに分割: ChronoLocalDate、ChronoOffsetDateTime等
Chronologyのサブクラス
• ISOChronology - ISO 8601(標準)
• JapaneseChronology - 和暦(日本)
• ThaiBuddhistChronology - 仏暦(タイ)
• MinguoChronology - 民国紀元(台湾)
• HijrahChronology - イスラム暦
日付・時刻演算
• DateTime、Period、Instant、Durationはそれ自身が加算・減算機能を持つ
•フィールドを表すクラス・列挙型が各種演算を提供:• Year → うるう年判定• Month → 月の日数取得• DayOfWeek → 曜日取得
フォーマット機能
• DateTimeFormatter: 出力形式をカスタマイズする
• DateTimeFormatterBuilderから比較的簡単にDateTimeFormatterを生成可能
• java.text.DateFormatはJSR 310では使用できない
Examples
// 今日の日付を取得→dateLocalDate date = LocalDate.now();
// 2012年11月10日→dateLocalDate date = LocalDate.of(2012, 11, 10);
// 今日の日付→d1// 3日後の日付→d2LocalDate d1 = LocalDate.now();LocalDate d2 = d1.plusDays(3);
// 今日の日付→date// 今日の16時30分→dateTimeLocalDate date = LocalDate.now();LocalDateTime dateTime = date.atTime(16, 30);
// 今日の日時→dateTime// 今日の日付→dateLocalDateTime dateTime = LocalDateTime.now();LocalDate date = LocalDate.from(dateTime);
// date: 1992年10月8日 (うるう年)// → leap = trueLocalDate date = LocalDate.of(1992, 10, 8);boolean leap = Year.from(date).isLeap();
// 今日の日付→date// dateを標準出力へLocalDate date = LocalDate.now();System.out.println(date.toString());
2012-11-10
出力結果
// 今日の日付(和暦)→dateJapaneseChronology chrono = JapaneseChronology.INSTANCE;ChronoLocalDate<JapaneseChronology> jdate = chrono.date(LocalDate.now());System.out.println(jdate);
H24-11-10
出力結果
Compatibility
java.util.Dateを改修(OpenJDK8)
•コンストラクタ Date(Instant instant)⇔コンストラクタ Date(long date)
• Instant toInstant() メソッド⇔long getTime() メソッド
※java.util.Calendarにも同様の改修
// OffsetDateTimeからInstantを取得// 取得したInstantからDateを生成OffsetDateTime dateTime = OffsetDateTime.now();Instant instant = dateTime.toInstant();Date date = new Date(instant);
他のAPIとの連携
•将来的にはJPA、JAXB等へ展開予定
•ただし現時点では具体的アクションなし
• JPA連携は早期実現を目指して計画中、とのこと(いつになることやら…)
Conclusion
JSR 310とは何なのか?
• JSR 310はjava.util.Dateの欠点をすべて解決しようとする野心的試み
•過去との互換性を断ち切ることで、日付・時刻APIの理想を追求した
•正直やり過ぎ感も否めないが、既存APIの問題点の多くを解決した点は評価
JSR 310のリソース
JSR 310 Specificationhttp://jcp.org/en/jsr/detail?id=310
JSR 310 RI “ThreeTen”http://threeten.sourceforge.nethttps://github.com/ThreeTen/threeten
Introduction to Date and Time APIHASUNUMA [email protected]: @btnrouge