這周在閱讀《阿里巴巴Java開發手冊》時,在並發處理一節的日期處理中,其強調SimpleDateFormat 是線程不安全的類,一般不要定義為 static 變量,如果
定義為 static,必須加鎖,或者使用 DateUtils 工具類。並且建議如果是 JDK8 的應用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter
代替 SimpleDateFormat,官方給出的解釋:simple beautiful strong immutable thread-safe。但是,這些JDK1.8新的特性以前都沒有用過,因此,學習了下。
一、介紹
Java對日期,日歷及時間的處理一直以來都飽受詬病,尤其是它決定將java.util.Date定義為可修改的以及將SimpleDateFormat實現成非線程安全的。
因此,Java 8引入了一套全新的時間日期API。關於這個新的時間日期庫的最大的優點就在於它定義清楚了時間日期相關的一些概念,比方說,瞬時時間(Instant),
持續時間(duration),日期(date),時間(time),時區(time-zone)以及時間段(Period)。同時它也借鑒了Joda庫的一些優點,比如將人和機器對時間日期的
理解區分開的。Java 8仍然延用了ISO的日歷體系,並且與它的前輩們不同,java.time包中的類是不可變且線程安全的。
二、重要的類介紹
新的時間及日期API位於java.time包中,下面是里面的一些關鍵的類:
(1)Instant:它代表的是時間戳
(2)LocalDate:不包含具體時間的日期,比如2014-01-14。它可以用來存儲生日,周年紀念日,入職日期等。
(3)LocalTime:它代表的是不含日期的時間
(4)LocalDateTime:它包含了日期及時間,不過還是沒有偏移信息或者說時區。
(5)ZonedDateTime:這是一個包含時區的完整的日期時間,偏移量是以UTC/格林威治時間為基准的。
(6)Period:包含的是兩個日期之間的天、月、年數差值
(7)Duration:包含是兩個日期時間間隔的秒以及納秒數
下面分別對每個類給出一些小例子,進行介紹。
三、例子
(1)Instant類
/*
Instant學習
*/
Instant now = Instant.now();
System.out.println(now.toString());
//毫秒
System.out.println(now.get(ChronoField.MICRO_OF_SECOND));
// 微秒
System.out.println(now.get(ChronoField.MICRO_OF_SECOND));
// 納秒
System.out.println(now.get(ChronoField.NANO_OF_SECOND));
// 毫秒轉Instant
LocalDateTime localDateTime = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
// 2018-01-14T11:03:35.002
System.out.println(localDateTime);
(2)LocalDate類
/*
LocalDate學習
*/
LocalDate now = LocalDate.now();
System.out.println(now.toString());
//日期加上1天
LocalDate plusDay = now.plusDays(1);
System.out.println(plusDay.toString());
//日期加上一周
LocalDate plusWeek = now.plusWeeks(1);
System.out.println(plusWeek.toString());
//計算當年前的第52天是幾月幾號
System.out.println("今年的第52天是:" + now.withDayOfYear(52));
//字符串轉日期
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
TemporalAccessor dateTempora = dateTimeFormatter.parse("2018-01-14");
LocalDate date = LocalDate.from(dateTempora);
System.out.println(date);
//格式化日期
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyyMMdd");
String dateStr = dateTimeFormatter1.format(now);
System.out.println(dateStr);
(3)LocalTime類
/*
LocalTime學習
*/
LocalTime now = LocalTime.now();
System.out.println(now.toString());
//時間加上12個小時
System.out.println("plus 12 hours: " + now.plusHours(12));
(4)LocalDateTime類
/*
LocalDateTime學習
*/
// 獲得當前日期時間
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 字符串轉日期時間。
DateTimeFormatter strToDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
TemporalAccessor dateTemporal = strToDateFormatter.parse("2017-01-01 12:12:13");
LocalDate date = LocalDate.from(dateTemporal);
System.out.println(date);
// 格式化日期時間
DateTimeFormatter dateToStrFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
String dateStr = dateToStrFormatter.format(now);
System.out.println(dateStr);
(5)Period類
/*
Period學習
*/
LocalDate startDate = LocalDate.now();
LocalDate endDate = startDate.plusDays(1);
Period period = Period.between(startDate, endDate);
System.out.println("間隔的天數" + period.getDays());
System.out.println("間隔的月數:" + period.getMonths());
System.out.println("間隔的年數:" + period.getYears());
// 直接使用日期類中的方法計算日期間隔
long days = startDate.until(endDate, ChronoUnit.DAYS);
System.out.println("間隔的天數:" + days);
long weeks = startDate.until(endDate, ChronoUnit.WEEKS);
System.out.println("間隔的周數:" + weeks);
(6)Duration類
/*
Duration學習
*/
LocalDateTime start = LocalDateTime.now();
LocalDateTime end = start.plusDays(1);
Duration duration = Duration.between(start, end);
System.out.println("間隔的秒數:" + duration.get(ChronoUnit.SECONDS));
System.out.println("間隔的納秒數:" + duration.get(ChronoUnit.NANOS));