摘要:概述簡介引入了一套全新的時間日期,操作起來更簡便??梢允褂玫逆i解決的線程安全問題測試方法使用進行格式化,是線程安全的時區(qū)設置帶時區(qū)的時間本文首發(fā)于凌風博客新特性之新的時間日期作者凌風
1. 概述 1.1 簡介
Java 8 引入了一套全新的時間日期API,操作起來更簡便。簡單介紹下,LocalDate和LocalTime和LocalDateTime的使用;
java.util.Date月份從0開始,java.time.LocalDate月份從1開始并且提供了枚舉。
java.util.Date和SimpleDateFormatter都不是線程安全的,而LocalDate和LocalTime和最基本的String一樣,是不變類型,不但線程安全,而且不能修改,它們分別使用 ISO-8601 日歷系統(tǒng)的日期和時間,它們提供了簡單的日期或時間,并不包含當前的時間信息,也不包含與時區(qū)相關的信息。
注 : ISO-8601 日歷系統(tǒng)是國際標準化組織制定的現(xiàn)代公民的日期和時間的表示法1.3 環(huán)境 2. LocalDate、LocalTime、LocalDateTime
LocalDate、LocalTime、LocalDateTime 三者的使用方式基本一致,所以我們這里就以 LocalDateTime 為例進行索命
2.1 實例@Test public void t1() { // 獲取當前時間 LocalDateTime ldt1 = LocalDateTime.now(); System.out.println(ldt1); // 獲取指定的時間 LocalDateTime ldt2 = LocalDateTime.of(2018, 12, 10, 10, 10, 10); System.out.println(ldt2); // 加兩年 LocalDateTime ldt3 = ldt1.plusYears(2); System.out.println(ldt3); // 減兩個月 LocalDateTime ldt4 = ldt1.minusYears(2); System.out.println(ldt4); // 獲取年月日時分秒 System.out.println(ldt1.getYear()); System.out.println(ldt1.getMonthValue()); System.out.println(ldt1.getDayOfMonth()); System.out.println(ldt1.getHour()); System.out.println(ldt1.getMinute()); System.out.println(ldt1.getSecond()); }2.2 Instant : 時間戳
使用 Unix 元年 1970年1月1日 00:00:00 所經歷的毫秒值
@Test public void t2() { Instant ins = Instant.now(); //默認使用 UTC 時區(qū) System.out.println(ins); // 時間偏移量 OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8)); System.out.println(odt); // 獲取毫秒值 System.out.println(ins.getNano()); // 對于元年開始進行運算 Instant ins2 = Instant.ofEpochSecond(60); System.out.println(ins2); }2.3 Duration : 用于計算兩個“時間”間隔
@Test public void t3() throws InterruptedException { // 時間戳 Instant ins1 = Instant.now(); Thread.sleep(1000); Instant ins2 = Instant.now(); Duration duration = Duration.between(ins1, ins2); System.out.println("所耗費時間為:" + duration.toMillis()); System.out.println("--------------------------------"); // LocalTime LocalTime lt1 = LocalTime.now(); Thread.sleep(1000); LocalTime lt2 = LocalTime.now(); System.out.println("所耗費時間為:" + Duration.between(lt1, lt2).toMillis()); }2.4 Period : 用于計算兩個“日期”間隔
@Test public void t5() { LocalDate ld1 = LocalDate.of(2017, 1, 1); LocalDate ld2 = LocalDate.now(); Period period = Period.between(ld1, ld2); System.out.println("相差" + period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "天"); }2.5 日期的操作
TemporalAdjuster 時間校正器,有時我們可能需要獲取例如:將日期調整到下個周日等操作。
TemporalAdjusters 該類通過靜態(tài)方法提供了大量的常用 TemporalAdjuster 的實現(xiàn)。
@Test public void t6() { LocalDateTime ldt = LocalDateTime.now(); // 指定這個月的一個固定日期 LocalDateTime ldt2 = ldt.withDayOfMonth(10); System.out.println(ldt2); // 獲取下個周日 LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); System.out.println("獲取下個周日 : " + ldt3); // 自定義:獲取下個工作日 LocalDateTime ldt5 = ldt.with((l) -> { LocalDateTime ldt6 = (LocalDateTime) l; DayOfWeek dayOfWeek = ldt6.getDayOfWeek(); if (dayOfWeek.equals(DayOfWeek.FRIDAY)) { return ldt6.plusDays(3); } else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) { return ldt6.plusDays(2); } else { return ldt6.plusDays(1); } }); System.out.println("獲取下個工作日 : " + ldt5); }3. DateTimeFormatter 3.1 簡介
在 JDK 1.8 中可以使用 DateTimeFormatter 來代替 SimpleDateFormat 進行日期的格式化,而且 DateTimeFormatter 是線程安全的
3.2 實例@Test public void t8() { DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime ldt = LocalDateTime.now(); // 將日期格式化為字符串,兩種方式否可以 String dtfDate = dtf.format(ldt); String ldtDate = ldt.format(dtf); System.out.println("dtfDate : " + dtfDate); System.out.println("ldtDate : " + ldtDate); // 將字符串格式化為 LocalDateTime LocalDateTime ldt2 = LocalDateTime.parse(dtfDate, dtf); System.out.println("時間為 : " + ldt2); }3.3 線程安全
在多線程使用 SimpleDateFormat 進行格式化日期的時候會有線程安全問題。
@Test public void t1() throws Exception { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Callabletask = new Callable () { @Override public Date call() throws Exception { return sdf.parse("2018-12-10"); } }; ExecutorService executor = Executors.newFixedThreadPool(10); List > results = new ArrayList<>(); for (int i = 0; i < 10; i++) { results.add(executor.submit(task)); } for (Future future : results) { System.out.println(future.get()); } executor.shutdown(); }
可以使用 ThreadLocal 的鎖解決 SimpleDateFormat 的線程安全問題
import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class DateFormatThreadLocal { private static final ThreadLocaldf = new ThreadLocal () { protected DateFormat initialValue() { return new SimpleDateFormat("yyyy-MM-dd"); } }; public static final Date convert(String source) throws ParseException { return df.get().parse(source); } }
測試方法
@Test public void t2() throws Exception { Callabletask = new Callable () { @Override public Date call() throws Exception { return DateFormatThreadLocal.convert("2018-12-10"); } }; ExecutorService executor = Executors.newFixedThreadPool(10); List > results = new ArrayList<>(); for (int i = 0; i < 10; i++) { results.add(executor.submit(task)); } for (Future future : results) { System.out.println(future.get()); } executor.shutdown(); }
使用 DateTimeFormatter 進行格式化,DateTimeFormatter 是線程安全的
@Test public void t3() throws Exception { DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); Callable4. 時區(qū)設置task = new Callable () { @Override public LocalDate call() throws Exception { return LocalDate.parse("2018-12-10",dtf); } }; ExecutorService executor = Executors.newFixedThreadPool(10); List > results = new ArrayList<>(); for (int i = 0; i < 10; i++) { results.add(executor.submit(task)); } for (Future future : results) { System.out.println(future.get()); } executor.shutdown(); }
@Test public void t2() { LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); System.out.println(ldt); // 帶時區(qū)的時間 ZonedDateTime zdt = ldt.atZone(ZoneId.of("Asia/Shanghai")); System.out.println(zdt); }
本文首發(fā)于凌風博客:Java 8 新特性之新的時間日期 API
作者:凌風
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/72779.html
摘要:上一篇文章,小樂給大家?guī)砹诵绿匦灾?,接下來本文將會給大家介紹新特性之前言通過發(fā)布新的來進一步加強對日期與時間的處理。 上一篇文章,小樂給大家?guī)砹薐ava8新特性之Optional,接下來本文將會給大家介紹Java8新特性之Date API 前言: Java 8通過發(fā)布新的Date-Time API來進一步加強對日期與時間的處理。 舊版的 Java 中,日期時間 API 存在諸多問題...
摘要:新特性掌握的引入,可以擴展的內容,使在某種形式上實現(xiàn)了多重繼承,更加靈活不能被實例化示例代碼需要注意的是,的繼承順序來自當前類的成員覆蓋了的方法,而則覆蓋了被繼承的方法當多個被同一個類使用的時候,會出現(xiàn)方法沖突的情況,使用關鍵詞解決示 PHP 5.4新特性 掌握 traits trait的引入,可以擴展class的內容,使class在某種形式上實現(xiàn)了多重繼承,更加靈活 t...
摘要:合并日期和時間這個復合類名叫,是和的合體。截至目前,我們介紹的這些日期時間對象都是不可修改的,這是為了更好地支持函數(shù)式編程,確保線程安全,保持領域模式一致性而做出的重大設計決定。 新的日期和時間API Java的API提供了很多有用的組件,能幫助你構建復雜的應用。不過,Java API也不總是完美的。我們相信大多數(shù)有經驗的程序員都會贊同Java 8之前的庫對日期和時間的支持就非常不理想...
摘要:處理日期日歷和時間的不足之處將設定為可變類型,以及的非線程安全使其應用非常受限。最完整的日期時間,包含時區(qū)和相對或格林威治的時差。獲取當前的日期中的用于表示當天日期。 簡介 伴隨 lambda表達式、streams 以及一系列小優(yōu)化,Java 8 推出了全新的日期時間API。 Java處理日期、日歷和時間的不足之處:將 java.util.Date 設定為可變類型,以及 SimpleD...
摘要:于是抽時間看了看以后各個版本的特性,做了一個總結。年和公開版本發(fā)布,取名為。此后對應版本就是,。發(fā)布,是一個重大版本更新。在此之后,就是每六個月發(fā)布一次新版本。以上和參考資料聊了一些關于的歷史,下面我們看看各個版本有那些新特性。 【這是 ZY 第 11 篇原創(chuàng)技術文章】 某天在網(wǎng)上閑逛,突然看到有篇介紹 Java 11 新特性的文章,頓時心里一驚,畢竟我對于 Java 的版本認識...
閱讀 1337·2021-11-11 11:00
閱讀 3069·2021-09-24 09:47
閱讀 5005·2021-09-22 15:53
閱讀 976·2021-09-10 10:50
閱讀 3219·2021-09-01 11:40
閱讀 1178·2019-08-30 15:55
閱讀 480·2019-08-30 12:49
閱讀 1063·2019-08-29 17:12