Java8 time
-
Upload
koji-lin -
Category
Technology
-
view
4.876 -
download
5
Transcript of Java8 time
![Page 1: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/1.jpg)
java.time.*@kojilin
2014/03/29@TWJUG
![Page 2: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/2.jpg)
Java的Data和Time•java.util.Date
•Since 1.0
•java.util.Calendar
•Since 1.1
•java.time.*
•Since 1.8
•為取代而生
![Page 3: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/3.jpg)
Date•雖然叫 Date, 但實際上是 timestamp,
#toString 又帶有 time zone
•存取麻煩
•年是1900 + ?
•月份從 0 開始
•不支援國際化
•Unix time
![Page 4: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/4.jpg)
Calendar•為了國際化而導入
•雖然叫 Calendar, 但實際上是 Date 和 Time
•建立和編輯日期與時間
•存取和運算比 java.util.Date 稍好一點,但仍不敷使用
![Page 5: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/5.jpg)
Calendar.Builder
Calendar cal1 = new Calendar.Builder() .setDate(2014, Calendar.MARCH, 29) .build();
•Java 8 新增,讓建立和變更能方便一點
Calendar cal2 = new Calendar.Builder() .setCalendarType("japanese") .setFiled(YEAR, 1, DAY_OF_YEAR, 1) .build();
![Page 6: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/6.jpg)
java.time.*•JSR-310
•為了 JDK 設計
•從 Joda-Time 啓發和演化
•ISO 8601 為基礎
•Immutable
•Type-safe
•考慮到 XML 和 資料庫
![Page 7: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/7.jpg)
ISO-8601•國際標準化組織的國際標準ISO 8601是日期
和時間的表示方法
•hh:mm:ss.s
•YYYY-MM-DDThh:mm:ss
•nYnMnD
•Gregorian Calendar (1582)
![Page 8: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/8.jpg)
ThreeTen backport project
•https://github.com/ThreeTen/threetenbp
•JSR-310 backport to JDK 7
•最終會有一個釋出會和 JDK 8 正式版本相同
![Page 9: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/9.jpg)
以人的角度看時間? vs
以機器的角度看時間?
![Page 10: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/10.jpg)
機器•Instant
•從 Java Epoch 開始經過的時間
•1970-01-01T00:00:00Z
•支援到奈秒
•Duration
•兩個 Instant 之間的差距
•Clock
•模擬系統時鐘
![Page 11: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/11.jpg)
InstantInstant now = Instant.now();
//2014-03-29T14:23:25.223Z now.toString();
//2014-03-29T14:23:28.223Z now.plusSeconds(3);
//2014-03-27T14:23:25.223Z now.minus(2, ChronoUnit.DAYS);
![Page 12: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/12.jpg)
Duration•顯示時間的量
•使用 seconds 和 nanoseconds 表示
•toString 結果會是 PTnHnMnS
•顯示時可以用 hours,minutes,seconds 和 nanoseconds
•用 of 建立Duration.ofHours(2);
Duration.ofDays(1);
![Page 13: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/13.jpg)
•從兩個 Temporal 取得
!
•有 Day 相關的方法,但這邊的 Day 就是 24 Hours 的意思
// 兩個參數都必須支援 ChronoUnit.SECONDSDuration.between(LocalDateTime.now(), LocalDateTime.now().plusDays(2));
!
!
!
// 現在時間加 24LocalDateTime.now().plus( Duration.ofDays(1));
![Page 14: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/14.jpg)
人
•出生於 1983/12/11
•2月3日生
•營業時間是 14:00 到 22:00
•兩天,三小時
![Page 15: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/15.jpg)
日期與時間•LocalDate
•LocalTime
•LocalDateTime
•OffsetTime
•OffsetDateTime
•ZonedDateTime
![Page 16: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/16.jpg)
Local 系列•沒有帶時差和時區的資訊
•LocalDate
•12月5日生日
•LocalTime
•14:00 開始營業
•LocalDateTime
![Page 17: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/17.jpg)
LocalDateLocalDate now = LocalDate.now();
now.toString(); // 2014-03-29
now.getDayOfWeek(); // SATURDAY
now.getDayOfMonth(); // 29
now.isLeapYear(); // false
// 2014-04-10 now.plusDays(12).toString();
![Page 18: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/18.jpg)
LocalTimeLocalTime now = LocalTime.now();
now.toString(); // 14:20:42.270
now.getHour(); // 14
now.getMinute(); // 20
LocalTime.MIDNIGHT; // 00:00
![Page 19: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/19.jpg)
LocalDateTimeLocalDateTime now = LocalDateTime.now();
// 2014-03-29T14:20:42.270 now.toString();
now.getDayOfMonth(); // 29
now.getHour(); // 14
![Page 20: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/20.jpg)
•LocalDate <=> LocalDateTime
Local 之間的轉換
LocalDate localDate = LocalDate.now();
// LocalDate to LocalDateTimeLocalDateTime localDateTime = localDate.atTime(14, 20, 20);
// LocalDateTime to LocalDatelocalDate = localDateTime.toLocalDate();
![Page 21: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/21.jpg)
•LocalTime <=> LocalDateTime
LocalTime localTime = LocalTime.now();
// LocalTime to LocalDateTimeLocalDateTime localDateTime = localTime.atDate( LocalDate.of(2014, 3, 29));
// LocalDateTime to LocalTimelocalTime = localDateTime.toLocalTime();
![Page 22: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/22.jpg)
時差和 time zone•OffsetTime
•OffsetDateTime
•ZonedDateTime
•ZonedDateTime != OffsetDateTime
•時差是固定的,Zoned 則會依照狀況變換時差,例如:日光節約時間, 更改時差
![Page 23: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/23.jpg)
ZonedDateTime dateTime = ZonedDateTime.of( LocalDate.of(1975, 3, 31), LocalTime.of(23, 0), ZoneId.of("Asia/Taipei"));
!
//1975-03-31T23:00+08:00[Asia/Taipei]dateTime.toString();
//1975-04-01T01:00+09:00[Asia/Taipei]dateTime.plusHours(1);
•台灣1975日光節約時間爲4月1日到9月30日
![Page 24: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/24.jpg)
ZonedDateTime dateTime = ZonedDateTime.of( LocalDate.of(1979, 6, 30), LocalTime.of(23, 0), ZoneId.of("Asia/Taipei"));
!
//1979-06-30T23:00+09:00[Asia/Taipei]dateTime.toString();
•台灣1979日光節約時間爲7月1日到9月30日
![Page 25: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/25.jpg)
Time zone•ZoneOffset
•-18:00~+18:00(-12:00 ~ +14:00)
•ZoneRules
•切換的規則
•ZoneId
•例如 Asia/Taipei, +8
![Page 26: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/26.jpg)
Time zone data•tz database 有世界時區的分類和命名
•IANA Time Zone Database (TZDB)
•$JDK_HOME/jre/lib/tzdb.dat
•透過 ZoneRulesProvider 讀取
•一直有更新,所以記得要持續更新 JRE 或透過 Oracle 提供的工具更新
![Page 27: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/27.jpg)
ZoneRuleProvider•Service provider interface
•可以在 META-INF/services 自己提供
•系統預設是 TzdbZoneRuleProvider
•提供動態更新的方法
•帶來很多複雜的問題,例如:取消或減少暫存造成效能問題,或是程式中拿不同規則來做運算
•通常不建議動態更新
![Page 28: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/28.jpg)
public static boolean refresh() {
boolean changed = false;
for (ZoneRulesProvider provider : PROVIDERS) {
changed |= provider.provideRefresh();
}
return changed;
}
•ZoneRulesProvider.refresh
![Page 29: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/29.jpg)
public static boolean refresh() {
boolean changed = false;
for (ZoneRulesProvider provider : PROVIDERS) {
changed |= provider.provideRefresh();
}
return changed;
}
•ZoneRulesProvider.refresh
•回傳的 boolean 可以讓應用程式知道有沒有更新
•系統預設的 provider#provideRefresh 是回傳 false
![Page 30: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/30.jpg)
DateTime 之間的轉換•LocalDateTime, LocalDate, LocalTime
•OffsetDateTime, OffsetTime
•ZonedDateTime
•補足需要的資訊或拿掉多餘的資訊就可以彼此間轉換
![Page 31: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/31.jpg)
DateTime 之間的轉換•LocalDateTime, LocalDate, LocalTime
•OffsetDateTime, OffsetTime
•ZonedDateTime
•補足需要的資訊或拿掉多餘的資訊就可以彼此間轉換
ZonedDateTime zdt = LocalDateTime.now() .atZone(ZoneId.of(“Asia/Taipei”));
LocalDateTime ldt = zdt.toLocalDateTime();
![Page 32: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/32.jpg)
Period•顯示時間的量
•使用 years, months 和 days 表示
•toString 結果會是 PnYnMnD
•用 of 建立
Period.ofWeeks(2);
![Page 33: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/33.jpg)
// 兩個參數都是 LocalDate Period.between(localDate1, LocalDate.now());
!
!
// 會是1975-04-01T23:00+09:00[Asia/Taipei]// 如果是 Duration, 則會是加上 24 小時ZonedDateTime.of( LocalDate.of(1975, 3, 31), LocalTime.of(23, 0), ZoneId.of("Asia/Taipei")) .plus(Period.ofDays(1));
•從兩個 LocalDate 取得
!
!
•用在 ZonedDateTime 時有考慮到 DST
![Page 34: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/34.jpg)
Formatting•用 DateTimeFormatter 取代
SimpleDateFormat
•Immutable - Thread safe
•可以利用 DateTimeFormatterBuilder 建立新格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
localDate.format(dateTimeFormatter);
offset.format(dateTimeFormatter);
![Page 35: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/35.jpg)
ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
!
LocalDate ld = LocalDate.parse("2011-12-03", ISO_LOCAL_DATE);
![Page 36: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/36.jpg)
Parsing•Instant, Date 和 Time 類別都用一樣方式
parse
•Period, Duration 用 ISO-8601格式
Instant.parse("…", dateTimeFormatter);
LocalDate.parse("…", dateTimeFormatter);
//1 Year 2 months 3days Period.parse("P1Y2M3D");
//2 days 3 hours 2.21 secondsDuration.parse("P2DT3H2.21S");
![Page 37: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/37.jpg)
•有些格式變得比較嚴格
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy/MM/dd");
//okLocalDate.parse("2014/03/02", formatter);
// error, DateTimeParseException//LocalDate.parse("2014/3/2", formatter);
//oknew SimpleDateFormat("yyyy/MM/dd") .parse("2014/3/2");
![Page 38: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/38.jpg)
Clock•透過 Inject 便於測試
•可以建立多種類型的 Clock
•讓測試可以獨立於 time zone
private Clock clock; // dependency inject
public void process(LocalDate event) {
if(event.isBefore(LocalDate.now(clock)){ ...
![Page 39: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/39.jpg)
//使用系統 Clock.systemDefaultZone();
//使用指定 ZoneId Clock.system(ZoneId.of("Asia/Tokyo"));
//固定時間 Instant instant = … ;
Clock.fixed(instant, ZoneIf.of("Asia/Taipei"));
//使用 30秒 tick 的時鐘Clock.tick(Clock.systemDefault(), Duration.ofSeconds(30));
![Page 40: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/40.jpg)
其他表示方式
•Year
•Month
•YearMonth
•MonthDay
•DayOfWeek
![Page 41: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/41.jpg)
現在LocalTime.now();
LocalTime.now(Clock.fixed(...));
LocalDate.now();
LocalDateTime.now();
OffsetDateTime.now();
![Page 42: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/42.jpg)
of•Static factory method
LocalDate.of(2014, 3, 29);
LocalTime.of(14, 5, 25);
Year.of(-1);
![Page 43: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/43.jpg)
at•Combines this object with another
LocalDate.of(2014, 3, 29).atTime( LocalTime.of(14, 5, 25));
![Page 44: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/44.jpg)
parse•Static factory method focussed on
parsing
LocalDate.parse("2014-03-29");
LocalTime.parse("14:23:20");
![Page 45: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/45.jpg)
with•The immutable equivalent of a setter
LocalDate.now().withMonth(4);
LocalTime.now().withMinute(30);
![Page 46: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/46.jpg)
plus, minus•Adds/Subtracts an amount to an object
LocalDate.now().plusDays(4) .plusYear(2);
LocalTime.now().plusMinutes(30) .plusHours(4) .minusSeconds(30);
![Page 47: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/47.jpg)
isBefore, isAfter•Check order
LocalDate.now().isBefore( LocalDate.of(2014, 12, 3));
LocalTime.now().isAfter( LocalTime.of(4, 12, 31));
![Page 48: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/48.jpg)
until, between•Amount of time until another
LocalDate.of(2014, 12, 3).until( LocalDate.of(2014, 12, 7), ChronoUnit.WEEKS);
ChronoUnit.DAYS.between( LocalDate.of(2014, 12, 3), LocalDate.of(2014, 12, 7));
![Page 49: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/49.jpg)
Chronology•Chronology
•曆
•Era
•紀年
•ChronoLocalDate
•ChronoLocalDateTime
•ChronoZonedDateTime
![Page 50: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/50.jpg)
民國年•MinguoDate
!
!
•和 ISO-8601 之間轉換
//Minguo ROC 103-03-29 MinguoDate date = MinguoDate.of(103, 3, 29);
LocalDate.from( MinguoDate.of(103, 3, 29));MinguoDate.from( LocalDate.now());
![Page 51: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/51.jpg)
與 Date 的轉換•LocalDate 和 LocalTime 本身沒有 Instant 值,所以必須要先轉換成能取得 Instant
•從 LocalDateTime 到 DateLocalDate now = LocalDate.now();
Instant instant = now.atZone(ZoneId.systemDefault()) .toInstant();
Date date = Date.from(instant);
![Page 52: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/52.jpg)
•從 Date 到 LocalDateTime
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime = LocalDateTime.ofInstant( instant, ZoneId.systemDefault());
![Page 53: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/53.jpg)
可擴充的介面設計•TemporalAccessor
•Temporal
•TemporalField
•TemporalAmount
•TemporalUnit
•TemporalQuery
•TemporalAdjuster
•可讀取的 Date&Time
•可修改的 Date&Time
•Date&Time 的 filed
•時間的量
•Date&Time 的單位
•查詢 Date&Time
•修改 Date&Time
![Page 54: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/54.jpg)
TemporalQuery
@FunctionalInterface
public interface TemporalQuery<R>{
R queryFrom(TemporalAccessor temporal);
}
![Page 55: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/55.jpg)
//DaysLocalDate.of(2014, 3, 29) .query(TemporalQueries.precision());
//2014-03-29T16:30:26.043 ZonedDateTime.now .query(LocalDateTime::from);
//SATURDAYLocalDate.of(2014, 3, 29) .query(DayOfWeek::from);
![Page 56: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/56.jpg)
TemporalAdjuster
@FunctionalInterface
public interface TemporalAdjuster{
Temporal adjustInfo(Temporal temporal);
}
![Page 57: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/57.jpg)
//2014-03-31 LocalDate.of(2014, 3, 29) .with(TemporalAdjusters.lastDayOfMondth());
//2014-04-05LocalDate.of(2014, 3, 29) .with(TemporalAdjusters.next( DayOfWeek.SATURDAY));
//2014-01-02LocalDate.now().with(t -> t.with(ChronoField .DAY_OF_YEAR, 2));
![Page 58: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/58.jpg)
JDBC• LocalDate
• LocalTime
• LocalDateTime
• OffsetTime
• OffsetDateTime
• DATE
• TIME WITHOUT TIME ZONE
• TIMESTAMP WITHOUT TIME ZONE
• TIME WITH TIME ZONE
• TIMESTAMP WITH TIMZ ZONE
![Page 59: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/59.jpg)
LocalDateTime << SQLResultSet rs = …;
…
java.sql.Time time = rs.getTime(…);
LocalTime lt = time.toLocalTime();
java.sql.Date date = rs.getDate(…);
LocalDate ld = date.toLocalDate();
java.sql.Timestamp ts = rs.getTimeStamp(…);
LocalDateTime ldt = ts.toLocalDateTime();
![Page 60: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/60.jpg)
LocalDateTime >> SQLPreparedStatement pstmt = …;
pstmt.setTime(1, Time.valueOf(LocalTime.now()));
pstmt.setDate(2, Date.valueOf(LocalDate.now()));
pstmt.setTimestamp(3, Timestamp.valueOf(LocalDateTime.now()));
![Page 61: Java8 time](https://reader030.fdocuments.net/reader030/viewer/2022013105/55630ff5d8b42a4b1d8b55c0/html5/thumbnails/61.jpg)
總結 JSR 310 的好處•良好的命名和 API 設計
•日期和時間的分別處理
•Immutable
•精確到奈秒
•多樣化的操作
•存取各種 filed 方便