Java8日期与时间API(LocalDate、LocalDateTime、Instant等)

代码来源:《Java8实战》
后续有更好的实例实时补充。

旧API的问题

Date与Calendar的问题:

  1. 同时存在Date和Calendar这两个类,增加调用时选择的困惑
  2. DateFormat只在Date中存在,但是非线程安全,多线程下会出问题。
  3. Date与Calendar类非final。final本质上是线程安全的,有利于各种函数式的方法调用。

新API各自职能

所有类都是不可变类型而且线程安全
LocalDate:提供日期信息,不含时间信息。不附带任何与时区相关的信息。
LocalTime:提供时间信息,不含日期信息。不附带任何与时区相关的信息。
LocalDateTime:LocalDate和LocalTime的合体。同时表示了日期和时间,但不带有时区信息。
Instant:面向机器,包含的是由秒及纳秒所构成的数字。
以Unix元年时间(传统设定为UTC时区1970年1月1日午夜时分)开始所经历的秒数进行计算。

Duration:以秒和纳秒表示某两个时间之间/时间段的长短
Period:以年、月或者日的方式表示某两个时间之间/时间段的长短

DateTimeFormatter:线程安全,时间格式,预先定义了许多实例,比如BASIC_ISO_DATE、ISO_LOCAL_DATE 

ZoneId:时区。ZoneRules类中定义了40个时区实例可以直接使用。
ZonedDateTime:参见下图,可以理解为有时区信息的LocalDateTime。

MonthDay:这个类组合了月份和日,去掉 了年,这意味着你可以用它判断每年都会发生事件。
YearMonth:另一个组合类,用于表示信用卡到期日、FD到期日、期货期权到期日等。
可以用这个类得到 当月共有多少天

Clock时钟类:获取当时的时间戳,或当前时区下的日期时间信息。
以前用到System.currentTimeMillis()和TimeZone.getDefault()的地方都可用Clock替换。

ZonedDateTime

LocalDate、LocalTime、LocalDateTime、Instant、 Duration & Period の API

通用方法列表:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
预定义的TemporalAdjuster,将日期调整到下个周日、下个工作日,或者是本月的最后一天。
在这里插入图片描述
在这里插入图片描述

LocalDate

// 创建
LocalDate today = LocalDate.now();
LocalDate date = LocalDate.of(2014, 3, 18);
LocalDate date = LocalDate.parse("2014-03-18");

// 获取各个日期
int year = date.getYear();
Month month = date.getMonth();
int day = date.getDayOfMonth();
DayOfWeek dow = date.getDayOfWeek();
int len = date.lengthOfMonth();
boolean leap = date.isLeapYear();
int year = date.get(ChronoField.YEAR);
int month = date.get(ChronoField.MONTH_OF_YEAR);
int day = date.get(ChronoField.DAY_OF_MONTH);

// withAttribute方法会创建对象的一个副本,并按照需要修改它的属性
LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.withYear(2011); // 2011-03-18
LocalDate date3 = date2.withDayOfMonth(25); // 2011-03-25
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9); // 2011-09-25

// 以相对方式修改LocalDate对象的属性
LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.plusWeeks(1);
LocalDate date3 = date2.minusYears(3);
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);

// 使用预定义的TemporalAdjuster,将日期调整到下个周日、下个工作日,或者是本月的最后一天
LocalDate date1 = LocalDate.of(2014, 3, 18);
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY));
LocalDate date3 = date2.with(lastDayOfMonth());

// 打印输出几解析日期-时间对象
LocalDate date = LocalDate.of(2014, 3, 18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);
LocalDate date1 = LocalDate.parse("20140318", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);

// 判断日期先后
LocalDate tomorrow = LocalDate.of(2014, 1, 15);
if(tommorow.isAfter(today)){
    
    
    System.out.println("Tomorrow comes after today");
}
LocalDate yesterday = today.minus(1, DAYS);
if(yesterday.isBefore(today)){
    
    
    System.out.println("Yesterday is day before today");
}
Output:
Tomorrow comes after today
Yesterday is day before today

// isLeapYear()判断该实例是否是一个闰年
if(today.isLeapYear()){
    
    
   System.out.println("This year is Leap year");
}else {
    
    
    System.out.println("2014 is not a Leap year");
}

LocalTime

// 创建
LocalTime time = LocalTime.of(13, 45, 20);
LocalTime time = LocalTime.parse("13:45:20");

// 获取各个时间
int hour = time.getHour();
int minute = time.getMinute();
int second = time.getSecond();
// 操纵时间
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
System.out.println("Today is : " + today);
System.out.println("Date after 1 week : " + nextWeek);

LocalDateTime

// 创建 2014-03-18T13:45:20
LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20);
LocalDateTime dt2 = LocalDateTime.of(date, time); // 根据LocalDate与LocalTime
LocalDateTime dt3 = date.atTime(13, 45, 20);
LocalDateTime dt4 = date.atTime(time);
LocalDateTime dt5 = time.atDate(date);

// 转化为LocalDate与LocalTime
LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();

// 将LocalDateTime转换为Instant
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
Instant instantFromDateTime = dateTime.toInstant(romeZone);
// 得到LocalDateTime对象
Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);

Instant

Instant.ofEpochSecond(3);
Instant.ofEpochSecond(3, 0); // 3秒之后的0纳秒
Instant.ofEpochSecond(2, 1_000_000_000); // 2秒之后再加上100万纳秒( 1秒)
Instant.ofEpochSecond(4, -1_000_000_000); //4秒之前的100万纳秒( 1秒)

// 将LocalDateTime转换为Instant
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
Instant instantFromDateTime = dateTime.toInstant(romeZone);
// 得到LocalDateTime对象
Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);

Instant timestamp = Instant.now();
System.out.println("What is value of this instant " + timestamp);
Output :
What is value of this instant 2014-01-14T08:33:33.379Z

Duration与Period

// 创建Duration 
Duration d1 = Duration.between(time1, time2);
Duration d1 = Duration.between(dateTime1, dateTime2);
Duration d2 = Duration.between(instant1, instant2);

Duration threeMinutes = Duration.ofMinutes(3);
Duration threeMinutes = Duration.of(3, ChronoUnit.MINUTES);

// 创建Period 
Period tenDays = Period.between(LocalDate.of(2014, 3, 8), LocalDate.of(2014, 3, 18));

Period tenDays = Period.ofDays(10);
Period threeWeeks = Period.ofWeeks(3);
Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1);

DateTimeFormatter

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);

// 按照某个模式创建DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date1 = LocalDate.of(2014, 3, 18);
String formattedDate = date1.format(formatter);
LocalDate date2 = LocalDate.parse(formattedDate, formatter);

// 创建一个本地化的DateTimeFormatter
DateTimeFormatter italianFormatter =
DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN);
LocalDate date1 = LocalDate.of(2014, 3, 18);
String formattedDate = date.format(italianFormatter); // 18. marzo 2014
LocalDate date2 = LocalDate.parse(formattedDate, italianFormatter);
// 日期格式“MMM d yyyy”和“MMM dd yyyy”有一些微妙的不同
// 第一个格式可以解析“Jan 2 2014”和“Jan 14 2014”,而第二个在解析“Jan 2 2014”就会抛异常。
// 第二个格式里要求日必须是两位的。
// 如果想修正,你必须在日期只有个位数时在前面补零,就是说“Jan 2 2014”应该写成 “Jan 02 2014”。

// 构造一个DateTimeFormatter
DateTimeFormatter italianFormatter = new DateTimeFormatterBuilder()
	.appendText(ChronoField.DAY_OF_MONTH)
	.appendLiteral(". ")
	.appendText(ChronoField.MONTH_OF_YEAR)
	.appendLiteral(" ")
	.appendText(ChronoField.YEAR)
	.parseCaseInsensitive()
	.toFormatter(Locale.ITALIAN);

时区

ZoneId romeZone = ZoneId.of("Europe/Rome");
// TimeZone的转换
ZoneId zoneId = TimeZone.getDefault().toZoneId();

LocalDate date = LocalDate.of(2014, Month.MARCH, 18);
ZonedDateTime zdt1 = date.atStartOfDay(romeZone);
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
ZonedDateTime zdt2 = dateTime.atZone(romeZone);
ZonedDateTime dateAndTimeInNewYork  = ZonedDateTime.of(date , romeZone );
Instant instant = Instant.now();
ZonedDateTime zdt3 = instant.atZone(romeZone);

// 将LocalDateTime转换为Instant
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
Instant instantFromDateTime = dateTime.toInstant(romeZone);
// 得到LocalDateTime对象
Instant instant = Instant.now();
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);

// 比较通用的表达时区的方式是利用当前时区和UTC/格林尼治的固定偏差
// 纽约时区落后于伦敦5小时
ZoneOffset newYorkOffset = ZoneOffset.of("-05:00");
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45);
OffsetDateTime dateTimeInNewYork = OffsetDateTime.of(date, newYorkOffset);

猜你喜欢

转载自blog.csdn.net/weixin_38370441/article/details/112335489