【Java8】新的日期和时间API

特性

Java8在java.time包中提供了很多新的类,它们的实例都是不可变对象,线程安全。

LocalDate

它只提供了简单的日期,不包含当天的时间信息。

  • 常用创建方式
LocalDate date = LocalDate.of(2018,6,17);
LocalDate date = LocalDate.now();
  • 获取特定值
int year = date.getYear();           //2018
Month month = date.getMonth();       //JUNE
int day = date.getDayOfMonth();      //17
DayOfWeek dow = date.getDayOfWeek(); //SUNDAY
int len = date.lengthOfMonth();      //30(days in JUNE)
boolean leap = date.isLeapYear();    //false(not a leap year)

LocalTime

类似的,一天中的时间,比如21:06:20,可以用LocalTime类表示。

  • 常用创建方式
LocalTime time = LocalTime.of(21,6,20);
LocalTime time = LocalTime.now();
  • 获取特定值
int hour = time.getHour();      //21
int minute = time.getMinute();  //6
int second = time.getSecond();  //20
  • LocalTime/LocalDate可以通过解析字符串创建,使用静态方法parse。无法解析时,会抛DateTimeParseException
LocalDate date = LocalDate.parse("2018-06-17");
LocalTime time = LocalTime.parse("21:06:20");

LocalDateTime

它是LocalDate和LocalTime的合体,同时表示了日期和时间,但不带时区信息。

  • 常用创建方式
LocalDateTime dt1 = LocalDateTime.of(2018,Month.JUNE,17,21,29,20);
LocalDateTime dt2 = LocalDateTime.of(date,time);
  • 其他操作
//通过各自的atTime或者atDate方法,创建一个LocalDateTime对象
LocalDateTime dt3 = date.atTime(21,6,20);
LocalDateTime dt4 = date.atTime(time); 
LocalDateTime dt5 = time.atDate(date); 

//通过LocalDateTime的toLocalTime或者toLocalDate方法,从中提取LocalTime或者LocalDate
LocalDate date1 = dt1.toLocalDate();
LocalDate time1 = dt1.toLocalTime();

转换

Java8添加的日期-时间对象都是不可修改的,这是为了更好地支持函数式编程,确保线程安全。不过,它也提供了一些便利的方法来创建这些对象的修改版本。每次的修改版都是一个新的对象。

LocalDate date1 = LocalDate.of(2018,6,18);   //2018-06-18
LocalDate date2 = date1.withYear(1994);      //1994-06-18
LocalDate date3 = date2.withDayOfMonth(25);  //1994-06-25
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR,9);  //1994-09-25

LocalDate date5 = date1.plusWeeks(1);  //2018-06-25
LocalDate date6 = date5.minusYears(3); //2015-06-25
LocalDate date7 = date6.plus(6,ChronoUnit.MONTHS); //2015-12-25

时间差

Java8提供了Duration类和Period类来处理时间差。Duration通常用于计算时间量,Period通常用于计算日期量。

  • 常用创建方式
//Java8引入的时间类都实现了Temporal接口,它定义了如何读取和操纵为时间建模的对象的值
Duration d1 = Duration.between(Temporal startInclusive, Temporal endExclusive);
Period p1 = Period.between(LocalDate startDateInclusive, LocalDate endDateExclusive);

Duration d2 = Duration.ofMinutes(3);
Duration d3 = Duration.of(3,ChronoUnit.MINUTES);
Period p2 = Period.ofDays(10);
Period twoYearsSixMonthsOneDay = Period.of(2,6,1);
  • 示例
LocalDate startDate = LocalDate.now();
LocalDate endDate = date1.plus(1, ChronoUnit.MONTHS);
Period period = Period.between(startDate, endDate);
System.out.println(period);  //打印结果:P1M

LocalTime startTime = LocalTime.now();
Duration twoHours = Duration.ofHours(2);
LocalTime endTime = time1.plus(twoHours);
Duration duration = Duration.between(startTime, endTime);
System.out.println(duration); //打印结果:PT2H
  • 计算LocalDateTime类型的时间差只能使用Duration。
  • between方法计算时,假如两个参数类型不一致,以第一个参数类型为准,第二个参数类型会转换为第一个参数类型。

格式化

处理日期和时间对象时,格式化以及解析日期-时间对象是另一个非常重要的功能。新的java.time.formate包就是特别为这个目的而设计的。这个包中,最重要的类是DateTimeFormatter。创建格式器的最简单方法是通过它的静态工厂方法以及常量。下面是用常量创建格式器的两种方式:

DateTimeFormatter.BASIC_ISO_DATE
DateTimeFormatter.ISO_LOCAL_DATE

所有的DateTimeFormatter实例都能用于以一定的格式创建代表特定日期或时间的字符串,例如:

LocalDate date = LocalDate.of(2018,6,18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE);  //20180617
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);  //2018-06-17

你也可以通过解析代表日期的字符串重新创建该日期对象。

LocalDate date1 = LocalDate.parse("20180618",DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2018-06-18",DateTimeFormatter.ISO_LOCAL_DATE);

DateTimeFormatter类还支持一个静态工厂方法,它可以按照某个特定的模式创建格式器:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date3 = LocalDate.of(2018,6,18);
String formattedDate = date3.format(formatter);              // 18/06/2018
LocalDate date4 = LocalDate.parse(formattedDate,formatter);  // 2018-06-18 

这段代码中,LocalDate的formate方法使用指定的模式生成了一个代表该日期的字符串。紧接着,静态的parse方法使用同样的格式解析了刚才生成的字符串,并重建了该日期对象。

LocalDate 与 Date 的转换

public static LocalDate dateToLocalDate(Date date){
  Instant instant = date.toInstant();
  ZoneId zoneId = ZoneId.systemDefault();
  LocalDate result = instant.atZone(zoneId).toLocalDate();
  return result;
}

public static Date localDateToDate(LocalDate localDate){
  ZoneId zoneId = ZoneId.systemDefault();
  ZonedDateTime zonedDateTime = localDate.atStartOfDay(zoneId);
  Date result = Date.from(zonedDateTime.toInstant());
  return result;
}

LocalDate与Timestamp的转换

public static LocalDate timeStampToLocalDate(Timestamp timestamp){
  return timestamp.toLocalDateTime().toLocalDate();
}

参考资料:https://docs.oracle.com/javase/8/docs/technotes/guides/datetime/index.html

你可能感兴趣的:(Java)