Java 8
新的日期和時間 API
為什麼需要新的
Date API ?
Date date = new Date(114, 2, 18);package com.balicanta.onlyfocus;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SimpleDateFormatThreadUnsafetyExample {
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
public static void main(String[] args) {
String dateStr = "2018-06-22T10:00:00";
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable task = new Runnable() {
@Override
public void run() {
parseDate(dateStr);
}
};
for(int i = 0; i < 100; i++) {
executorService.submit(task);
}
executorService.shutdown();
}
private static void parseDate(String dateStr) {
try {
Date date = simpleDateFormat.parse(dateStr);
System.out.println("Successfully Parsed Date " + date);
} catch (ParseException e) {
System.out.println("ParseError " + e.getMessage());
} catch (Exception e) {
e.printStackTrace();
}
}
}想一下幾個問題
-
輸入 2019/09/21 字串,回傳 30 天後的 Date
-
給你兩個 Date Object 中間差幾天?
-
資料庫裡面存 Timestamp 頁面上顯示 幾天前上傳
-
使用者輸入一個日期,回傳該日期月份的最後一天
為什麼需要新的
Date API ?
- 可讀性
- 易用性
- Thread Safe
本地日期 Local Date
Local Date
// 取得現在的日期
LocalDate localDate = LocalDate.now();
// 傳入數字,取得日期
LocalDate.of(2015, 02, 20);
// 透過字串轉換成日期
LocalDate.parse("2015-02-20");Local Date
// 現在日期加一天
LocalDate tomorrow = LocalDate.now().plusDays(1);
// 現在的日期減一個月
LocalDate previousMonthSameDay = LocalDate.now().minus(1, ChronoUnit.MONTHS);
// 取得今天是星期幾?
DayOfWeek sunday = LocalDate.parse("2016-06-12").getDayOfWeek();
// 取得今天是一個月的第幾天?
int twelve = LocalDate.parse("2016-06-12").getDayOfMonth();
// 是否為閏年
boolean leapYear = LocalDate.now().isLeapYear();Local Date
// 兩兩日期的比較
boolean notBefore = LocalDate.parse("2016-06-12").isBefore(LocalDate.parse("2016-06-11"));
boolean isAfter = LocalDate.parse("2016-06-12").isAfter(LocalDate.parse("2016-06-11"));Local Date
// 透過現在的 Local Date 取得一個 LocalDate Time 的時間
LocalDateTime beginningOfDay = LocalDate.parse("2016-06-12").atStartOfDay();
// 透過現在的日期,平移到這個月的第一天
LocalDate firstDayOfMonth =
LocalDate.parse("2016-06-12").with(TemporalAdjusters.firstDayOfMonth());本地時間 Local Time
Local Time
// 取得現在時間,只有時間,沒有日期
LocalTime now = LocalTime.now();
// 透過字串取得時間
LocalTime sixThirty = LocalTime.parse("06:30");
// 透過數字取得時間
LocalTime sixThirty = LocalTime.of(6, 30);Local Time
// 加一個小時
LocalTime sevenThirty = LocalTime.parse("06:30").plus(1, ChronoUnit.HOURS);
// 取得小時
int six = LocalTime.parse("06:30").getHour();
// 兩者時間的比較
boolean isbefore = LocalTime.parse("06:30").isBefore(LocalTime.parse("07:30"));
本地日期與時間
LocalDateTime
本地日期與時間
LocalDateTime
// 取得本地日期時間
LocalDateTime.now();
// 透過數字取得
LocalDateTime.of(2015, Month.FEBRUARY, 20, 06, 30);
// 透過文字取得
LocalDateTime.parse("2015-02-20T06:30:00");
// 日期、時間的運算
localDateTime.plusDays(1);
localDateTime.minusHours(2);
有時區概念的時間
有時區概念的時間
// 透過字串取得 ZoneId
ZoneId zoneId = ZoneId.of("Europe/Paris");
// 取得所有的 ZoneId
Set<String> allZoneIds = ZoneId.getAvailableZoneIds();
// 透過字串,轉換一個具有 Zone ID 的字串
ZonedDateTime.parse("2015-05-03T10:15:30+01:00[Europe/Paris]");
Duration & Period
Period
// 取得兩個日期
LocalDate initialDate = LocalDate.parse("2007-05-10");
LocalDate finalDate = initialDate.plus(Period.ofDays(5));
// 取得兩者的差距天數
int five = Period.between(initialDate, finalDate).getDays();Duration
ocalTime initialTime = LocalTime.of(6, 30, 0);
LocalTime finalTime = initialTime.plus(Duration.ofSeconds(30));
long thirty = Duration.between(initialTime, finalTime).getSeconds();
時間與日期的格式化
時間與日期的格式化
LocalDateTime localDateTime = LocalDateTime.of(2015, Month.JANUARY, 25, 6, 30);
// 透過內建的 Formatter 完成
String localDateString = localDateTime.format(DateTimeFormatter.ISO_DATE);時間與日期的格式化
localDateTime
.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM))
.withLocale(Locale.UK);時間與日期的格式化
DateTimeFormatter italianFormatter = new DateTimeFormatterBuilder()
.appendText(ChronoField.DAY_OF_MONTH)
.appendLiteral(". ")
.appendText(ChronoField.MONTH_OF_YEAR)
.appendLiteral(" ")
.appendText(ChronoField.YEAR)
.parseCaseInsensitive()
.toFormatter(Locale.ITALIAN);今天要記得什麼?
今天要記得什麼?
- Java 8 針對 Date API 有全面性增強
- 把過去的 Date 分成
- LocalDate, LocalTime... TimeZoneDateTime
- 日期的移動變的很簡單
- 增加了 Duration & Period
- 相容於舊的 java.util.date & java.util.TimeStamp
- 但 Redick 沒有分享
Java 8新的日期和時間 API
By Balicanta Yao
Java 8新的日期和時間 API
- 182