天天看點

Java 8 日期API

Java 8 中的日期API相比以前更為簡潔,辨識度高,而且都是線程安全的。掌握常用的時間類方法有時可以節省許多額外的工作。關于各個類的介紹可以參考Java 8新特性(四):新的時間和日期API

值得注意的是,LocalTime 、LocalDate 與 LocalDateTime 類的構造器都是 private,這裡用了靜态工廠方法(static factory methods)。靜态工廠方法相比傳統的構造器有如下優點(參考Effective Java第二版):

  1. 靜态工廠方法在方法命名上更具有可讀性
  2. 靜态工廠方法可以在被調用的時候傳回同一個對象,而不是每次都建構一個新的對象
  3. 靜态工廠方法可以傳回該類型的子類對象
  4. 靜态工廠方法可以簡化參數化類型的對象建立

關于第四點,Java 7 已經開始支援泛型類型推導,并在Java 8 中得到了完善(Java8中對泛型目标類型推斷方法的改進)。

下面是應用新的API寫的一些例子,基本能夠滿足日常需要。

  • 擷取目前日期時間

LocalDate date = LocalDate.now();

LocalTime time = LocalTime.now();

LocalDateTime dateTime = LocalDateTime.now().withNano(0);

  • 擷取指定日期時間

LocalDate specDatefromString = LocalDate.parse(“2014-12-12”);

LocalDate specDate = LocalDate.of(2014, 2, 20);

specDate = LocalDate.ofYearDay(2015, 100);

specDate = LocalDate.ofEpochDay(200);//自1970年1月1日起200天後的日期

  • 擷取今天是今年的第幾天
int dayOfYear = LocalDate.now().getDayOfYear();
  • 上個月最後一天

LocalDate date = LocalDate.now();

// 不用考慮是28、29、30還是31天

LocalDate lastDayOfMonth = date.with(TemporalAdjusters.lastDayOfMonth());

  • 2015年11月第一個周一
LocalDate firstMondayInOneMonth = LocalDate.parse(“2015-11-11”).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
  • 日期加減與時間間隔

LocalTime time = LocalTime.now();

// 目前時間加20分鐘

LocalTime timeAfterPlus = time.plusMinutes(20);

// 目前時間減2小時

LocalTime timeAfterMinus = time.minusHours(2);

// 兩個時間間隔(機關:分鐘),如第二個參數比第一個大,結果為負數

long duration = ChronoUnit.MINUTES.between(time, timeAfterPlus);

  • 擷取兩個日期間的距離

LocalDate date = LocalDate.now();

Period period = Period.between(LocalDate.of(2014, 2, 10), date);

  • 日期判斷

LocalDate date = LocalDate.now();

LocalDate date1 = LocalDate.now();

// 判斷是否相等

boolean isEqual = date.equals(date1);

// 判斷是否在另一個日期之前

boolean isBefore = date.isBefore(date1);

// 判斷是否為閏年

boolean isLeapYear = date.isLeapYear();

  • 檢視時區

// 獲得所有時區

Set<String> allZone = ZoneId.getAvailableZoneIds();

ZoneId zone = ZoneId.systemDefault();

// 獲得美國時間

ZoneId zoneInUSA = ZoneId.of(“America/New_York”);

LocalTime timeInUSA = LocalTime.now(zoneInUSA);

  • 時間戳轉換
  1. 将時間戳轉換為日期

Instant second = Instant.ofEpochSecond(1234567890L);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

// 等同于 formatter.format(LocalDateTime.ofInstant(second, ZoneId.systemDefault()));

String time = LocalDateTime.ofInstant(second, ZoneId.systemDefault()).format(formatter);

// 另一種方法

LocalDateTime now = LocalDateTime.ofEpochSecond(12468312, 0, ZoneOffset.of("+8"));

  1. 日期轉換為時間戳

// 第一種方式

Instant instant1 = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant();

// 第二種方式

OffsetDateTime offsetTime = OffsetDateTime.now(ZoneId.systemDefault ());

ZoneOffset offset = offsetTime.getOffset();

Instant instant2 = LocalDateTime.now().toInstant(offset);

// 獲得絕對秒

long millisecond = instant1.getEpochSecond();