原来的Java的时间类Date、java.util.Calendar类都不太好,以语言无关方式格式化和解析日期或时间的 DateFormat 方法也有线程安全的问题
LocalDate 类,该类的实例是一个不可变对象,它只提供了简单的日期,并不含当天的时间信息。另外,它也不附带任何与时区相关的信息。
LocalDate date = LocalDate.of(2017, 9, 21); // 2017-09-21
int year = date.getYear(); 2017
Month month = date.getMonth(); SEPTEMBER
int day = date.getDayOfMonth(); 21
DayOfWeek dow = date.getDayOfWeek(); THURSDAY
int len = date.lengthOfMonth(); 30 (days in September)
boolean leap = date.isLeapYear(); false (not a leap year)
还可以使用工厂方法 now 从系统时钟中获取当前的日期:LocalDate today = LocalDate.now();
还可以通过传递一个 TemporalField 参数给 get 方法访问同样的信息。
使用 TemporalField 读取 LocalDate 的值
int year = date.get(ChronoField.YEAR);
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);
或者
int year = date.getYear();
int month = date.getMonthValue();
int day = date.getDayOfMonth();
LocalDate date = LocalDate.parse("2017-09-21");
这个复合类名叫 LocalDateTime,是 LocalDate 和 LocalTime 的合体。它同时表示了日期和时间,但不带有时区信息,你可以直接创建,也可以通过合并日期和时间对象创建
LocalDateTime dt1 = LocalDateTime.of(2014, Month.SEPTEMBER, 21, 13, 45, 20);
LocalDateTime dt2 = LocalDateTime.of(date, time);
LocalDateTime dt3 = date.atTime(13, 45, 20);
LocalDateTime dt4 = date.atTime(time);
LocalDateTime dt5 = time.atDate(date);
LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();
Duration 类的静态工厂方法 between 就是为这个目的而设计的。
Duration d1 = Duration.between(time1, time2);
Duration d1 = Duration.between(dateTime1, dateTime2);
Duration d2 = Duration.between(instant1, instant2);
由于 LocalDateTime 和 Instant 是为不同的目的而设计的,一个是为了便于人阅读使用,另一个是为了便于机器处理,因此不能将二者混用。如果你试图在这两类对象之间创建Duration,就会触发一个 DateTimeException 异常。
如果你已经有一个 LocalDate 对象,想要创建它的一个修改版,最直接也最简单的方法是使用 withAttribute 方法。withAttribute 方法会创建对象的一个副本,并按照需要修改它的属性。
LocalDate date1 = LocalDate.of(2017, 9, 21);
LocalDate date2 = date1.withYear(2011);
LocalDate date3 = date2.withDayOfMonth(25);
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 2);
采用更通用的 with 方法能达到同样的目的,它接受的第一个参数是一个 TemporalField对象
加一段时间,或者减一段时间,plus
LocalDate date1 = LocalDate.of(2017, 9, 21);
LocalDate date2 = date1.plusWeeks(1);
LocalDate date3 = date2.minusYears(6);
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);
import static java.time.temporal.TemporalAdjusters.*;
LocalDate date1 = LocalDate.of(2014, 3, 18); 2014-03-18
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY)); 2014-03-23
LocalDate date3 = date2.with(lastDayOfMonth()); 2014-03-31
新的java.time.format 包就是特别为这个目的而设计的
LocalDate date = LocalDate.of(2014, 3, 18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); 20140318
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); 2014-03-18
LocalDate date1 = LocalDate.parse("20140318", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);
时区是按照一定的规则将区域划分成的标准时间相同的区间。在 ZoneRules 这个类中包含了 40 个这样的实例。ZoneId romeZone = ZoneId.of("Europe/Rome");
LocalDate date = LocalDate.of(2014, Month.MARCH, 18);
JapaneseDate japaneseDate = JapaneseDate.from(date);