新的時間和日期API
在Java 8之前,所有關于時間和日期的API都存在各種使用方面的缺陷,主要有:
- Java的
和java.util.Date
類易用性差,不支援時區,而且他們都不是線程安全的;java.util.Calendar
- 用于格式化日期的類
被放在DateFormat
包中,它是一個抽象類,是以我們需要執行個體化一個java.text
對象來處理日期格式化,并且SimpleDateFormat
也是非線程安全,這意味着如果你在多線程程式中調用同一個DateFormat
對象,會得到意想不到的結果。DateFormat
- 對日期的計算方式繁瑣,而且容易出錯,因為月份是從0開始的,從
中擷取的月份需要加一才能表示目前月份。Calendar
LocalDate,LocalTime
初始化:
LocalDate ld = LocalDate.of(2018,9,9);
LocalTime lt = LocalTime.of(12,12,12);
擷取目前時間:
ld = LocalDate.now();
lt = LocalTime.now();
檢視詳情
int year = ld.getYear();
Month month = ld.getMonth();
int day = ld.getDayOfMonth();
DayOfWeek weekday = ld.getDayOfWeek();
int hour = lt.getHour();
int minute = lt.getMinute();
int second = lt.getSecond();
LocalDateTime
初始化
LocalDate ld = LocalDate.of(2018,9,9);
LocalTime lt = LocalTime.of(12,12,12);
LocalDateTime ldt = ld.atTime(lt);
LocalDateTime ldt1 = lt.atDate(ld);
localDateTime => localDate/localTime
ld = ldt.toLocalDate
lt = ldt.toLocalTime
parse
String => LocalDateTime
String s = “2013-01-02 12:22:22”;
DateTimeFormatter df = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);
LocalDateTime ldt = LocalDateTime.parse(s,df);
String => LocalDate/LocalTime
String sdate = “2013-01-02”;
String stime = “22:22:22”;
LocalDate ld = LocalDate.parse(sdate);
LocalTime lt = LocalTime.parse(stime);
Instant
Instant
用于表示一個時間戳,它與我們常使用的
System.currentTimeMillis()
有些類似,不過Instant可以精确到納秒(Nano-Second),
System.currentTimeMillis()
方法隻精确到毫秒(Milli-Second)。如果檢視
Instant
源碼,發現它的内部使用了兩個常量,seconds表示從1970-01-01 00:00:00開始到現在的秒數,nanos表示納秒部分(nanos的值不會超過999,999,999)。
Instant
除了使用
now()
方法建立外,還可以通過
ofEpochSecond
方法建立:
Instant instant = Instant.ofEpochSecond(120, 100000);
ofEpochSecond()
方法的第一個參數為秒,第二個參數為納秒,上面的代碼表示從1970-01-01 00:00:00開始後兩分鐘的10萬納秒的時刻
Duration
Duration
的内部實作與
Instant
類似,也是包含兩部分:seconds表示秒,nanos表示納秒。兩者的差別是
Instant
用于表示一個時間戳(或者說是一個時間點),而
Duration
表示一個時間段,是以
Duration
類中不包含
now()
靜态方法。可以通過
Duration.between()
方法建立
Duration
對象:
LocalDateTime from = LocalDateTime.of(2017, Month.JANUARY, 5, 10, 7, 0); // 2017-01-05 10:07:00
LocalDateTime to = LocalDateTime.of(2017, Month.FEBRUARY, 5, 10, 7, 0); // 2017-02-05 10:07:00
Duration duration = Duration.between(from, to); // 表示從 2017-01-05 10:07:00 到 2017-02-05 10:07:00 這段時間
long days = duration.toDays(); // 這段時間的總天數
long hours = duration.toHours(); // 這段時間的小時數
long minutes = duration.toMinutes(); // 這段時間的分鐘數
long seconds = duration.getSeconds(); // 這段時間的秒數
long milliSeconds = duration.toMillis(); // 這段時間的毫秒數
long nanoSeconds = duration.toNanos(); // 這段時間的納秒數
Duration
對象還可以通過
of()
方法建立,該方法接受一個時間段長度,和一個時間機關作為參數:
Duration duration1 = Duration.of(5, ChronoUnit.DAYS); // 5天
Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS); // 1000毫秒
Period
Period
在概念上和
Duration
類似,差別在于
Period
是以年月日來衡量一個時間段,比如2年3個月6天:
Period period = Period.of(2, 3, 6);
Period
對象也可以通過
between()
方法建立,值得注意的是,由于
Period
是以年月日衡量時間段,是以
between()
方法隻能接收
LocalDate
類型的參數:
Period period2 = Period.between(LocalDate.of(2017, 1, 5),LocalDate.of(2017, 2, 5));
Period
對象可以獲得時間段的長度:
int dayP2 = period2.getDays();
int monthP2 = period2.getMonths();
int yearP2 = period2.getYears()
注意,
Period
獲得的時間段長度不是總的長度,如:
Period period2 = Period.between(LocalDate.of(2017, 1, 5),LocalDate.of(2017, 2, 5));
int day = period2.getDays(); // day=0
時區
參考
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
public class LocalDateAndTime {
public static void main(String[] args) throws Exception {
LocalDate ld = LocalDate.of(2019,3,10);
LocalTime lt = LocalTime.of(11,12,12);
int year = ld.getYear();
System.out.println("年:" + year);
Month month = ld.getMonth();
System.out.println("月:" + month);
int day = ld.getDayOfMonth();
System.out.println("日" + day);
DayOfWeek weekday = ld.getDayOfWeek();
System.out.println("周" + weekday);
int hour = lt.getHour();
System.out.println("小時" + hour);
int minute = lt.getMinute();
System.out.println("分鐘" + minute);
int second = lt.getSecond();
System.out.println("秒" + second);
System.out.println(ld);
System.out.println(lt);
String sdate = "2013-01-02";
String stime = "22:22:22";
ld = LocalDate.parse(sdate);
lt = LocalTime.parse(stime);
System.out.println(ld);
System.out.println(lt);
ld = LocalDate.now();
lt = LocalTime.now();
System.out.println(ld);
System.out.println(lt);
System.out.println("=========");
String s = "2013-01-02 12:22:22";
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.parse(s,df);
System.out.println(ldt);
ldt = lt.atDate(ld);
System.out.println(ldt);
ldt = ld.atTime(lt);
System.out.println(ldt);
ld = ldt.toLocalDate();
lt = ldt.toLocalTime();
System.out.println(ld);
System.out.println(lt);
System.out.println("=========");
LocalDate hd = LocalDate.of(2019,3,10);
System.out.println(ld == hd);
System.out.println(ld.equals(hd));
LocalDateTime ss = ld.atStartOfDay();
System.out.println(ld);
System.out.println(ld.withMonth(1));
System.out.println(ld.withDayOfMonth(1));
LocalDate md = LocalDate.now();
System.out.println(ld);
System.out.println(md);
Long i = ld.toEpochDay()-md.toEpochDay()+1;
Long j = hd.toEpochDay()-ld.toEpochDay();
System.out.println(i);
System.out.println(j);
System.out.println((double)i/j*3);
System.out.println(Math.floor((double)i/j*3));
System.out.println(Math.ceil((double)i/j*3));
System.out.println("=========");
LocalDateTime from = LocalDateTime.of(2017, Month.JANUARY, 5, 10, 7, 0); // 2017-01-05 10:07:00
LocalDateTime to = LocalDateTime.of(2017, Month.FEBRUARY, 5, 10, 7, 0); // 2017-02-05 10:07:00
Duration duration = Duration.between(from, to); // 表示從 2017-01-05 10:07:00 到 2017-02-05 10:07:00 這段時間
long days = duration.toDays(); // 這段時間的總天數
System.out.println("天數" + days);
long hours = duration.toHours(); // 這段時間的小時數
System.out.println("小時數" + hours);
long minutes = duration.toMinutes(); // 這段時間的分鐘數
System.out.println("分鐘數" + minutes);
long seconds = duration.getSeconds(); // 這段時間的秒數
System.out.println("秒數" + seconds);
long milliSeconds = duration.toMillis(); // 這段時間的毫秒數
System.out.println("毫秒數" + milliSeconds);
long nanoSeconds = duration.toNanos(); // 這段時間的納秒數
System.out.println("納秒數" + nanoSeconds);
Duration duration1 = Duration.of(5, ChronoUnit.DAYS); // 5天
long days1 = duration1.toDays(); // 這段時間的總天數
System.out.println("天數1:" + days1);
Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS); // 1000毫秒
long milliSeconds2 = duration2.toMillis(); // 這段時間的毫秒數
System.out.println("毫秒數2:" + milliSeconds2);
System.out.println("=========");
Period period = Period.of(2, 3, 6);
int dayP1 = period.getDays();
int monthP1 = period.getMonths();
int yearP1 = period.getYears();
System.out.println("Period Days:" + dayP1 + ", Months:" + monthP1 + ", Years:" + yearP1);
// 2017-01-05 到 2017-02-05 這段時間
Period period2 = Period.between(LocalDate.of(2017, 1, 5),LocalDate.of(2017, 2, 5));
int dayP2 = period2.getDays();
int monthP2 = period2.getMonths();
int yearP2 = period2.getYears();
System.out.println("Period2 Days:" + dayP2 + ", Months:" + monthP2 + ", Years:" + yearP2);
period2 = Period.between(LocalDate.of(2017, 1, 4),LocalDate.of(2020, 3, 5));
dayP2 = period2.getDays();
monthP2 = period2.getMonths();
yearP2 = period2.getYears();
System.out.println("Period2 Days:" + dayP2 + ", Months:" + monthP2 + ", Years:" + yearP2);
System.out.println("Period獲得的時間段長度不是總的長度,比如獲得的天數,與月份和年份無關");
System.out.println("=========");
}
}