Java的日期時間API,一直有一些令人頭疼的問題。
有了 java.util.Date 又搞出個java.sql.Date,改個名字不行?
好好的new Date(year,month,day) 早早的就被標記為 @Deprecated,那時候還是jdk1.1,如今都java9了,還沒刪除。
好吧,又給了一個Calendar,每次一個操作,都感覺,IDE一行設置80個字符,是真不夠。
我想搞個純日期,那叫一個麻煩,相信很多人都這么寫:
Calendar cal=Calendar.getInstance(); cal.set(Calendar.HOUR,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); Date date=cal.getTime();
心塞~
貌似看起來Calendar比Date好一點,但他繼承了Date一個很惡心的特性,月份問題。
System.out.println(cal.getTime());//Fri Nov 17 12:00:00 CST 2017 System.out.println(cal.get(Calendar.MONTH));//10
java8終于有了個改觀,那就是引入了joda-time的API,雖然仍然沒有joda好用。
日期時間API將日期和時間分開為LocalDate和LocalTime;
既有日期又有時間,則使用 LocalDateTime;
改善了jdk的TimeZone,使用更優雅的ZoneId;
增加了 Instant 的概念,可以理解為時間線上的一個瞬間;
//獲取當前日期 LocalDate date1=LocalDate.now(); System.out.println(date1); //獲取指定日期 LocalDate date2=LocalDate.of(2017, 12, 24); System.out.println(date2); //獲取當月天日期 LocalDate minus = date1.minus(date1.getDayOfMonth()-1,ChronoUnit.DAYS); System.out.println(minus);
//LocalDate -> Date LocalDate localDate1=LocalDate.now(); ZoneId zoneId=ZoneId.systemDefault(); Instant instant=localDate1.atStartOfDay(zoneId).toInstant(); Date from = Date.from(instant); System.out.println(from); //Date 轉 LocalDate Date date2=new Date(); Instant instant = date2.toInstant(); ZoneId zoneId=ZoneId.systemDefault(); LocalDate localDate2 = instant.atZone(zoneId).toLocalDate(); System.out.println(localDate);
實際單純使用時間的場景,并沒有單純使用日期的時間多。而且,LocalDate的思路捋清楚,LocalTime的使用大同小異,以后再補充吧。
結合了LocalDate 和 LocalTime,也就是傳統意義上類似Date的時間。
LocalDate localDate = dt.toLocalDate(); LocalTime localTime = dt.toLocalTime();
Date 轉 LocalDateTime
Date date = new Date(); Instant instant = date.toInstant(); ZoneId zone = ZoneId.systemDefault(); LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); # LocalDateTime 轉 Date
LocalDateTime localDateTime = LocalDateTime.now(); ZoneId zone = ZoneId.systemDefault(); Instant instant = localDateTime.atZone(zone).toInstant(); Date date = Date.from(instant);
從前面的格式轉換可以看出。
Date -> Instant -(ZoneId)-> LocalDate
用文字描述,就是 Date 可以轉換為 Instant;Instant 可以借助ZoneId 轉換為LocalDate。反之亦然。
ZoneId zoneId=ZoneId.systemDefault(); System.out.println(zoneId); TimeZone tz=TimeZone.getDefault(); System.out.println(tz);
輸出:
Asia/Shanghai
sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
ZoneId忽略了哪些用處不大的信息,更清晰。如果必要的時候,可以在屬性 zoneId.getRules() 中獲取。
在日期計算上,引入的joda-time特性,實在太方便了。
比如,如果要得到本月的天的日期,那么以前我們需要這么做。
Calendar cal=Calendar.getInstance(); cal.set(Calendar.HOUR,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); cal.set(Calendar.DAY_OF_MONTH,1); System.out.println(cal.getTime());
現在呢?
LocalDate date=LocalDate.now().withDayOfMonth(1); System.out.println(date);
如果我們希望計算當前時間的前一天的時刻,以前需要這么做:
Calendar cal=Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1);
現在呢?
LocalDateTime date=LocalDateTime.now().minusDays(1);
既簡單,語義也更佳。支持鏈式語法,編碼方便。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。