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

代码来源:《Java8实战》
后续有更好的实例实时补充。
https://www.cnblogs.com/bestzrz/p/10425870.html

旧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);
//LocalDateTime -> TimeStamp
Timestamp localDateTimeToTimeStamp = Timestamp.valueOf(LocalDateTime.now());
System.out.println("LocalDateTime -> TimeStamp:  " + localDateTimeToTimeStamp);
// 转long
Long localDateTimeToLong = Timestamp.valueOf(LocalDateTime.now()).getTime();

long localDateTimeToLong = Timestamp.valueOf(LocalDateTime.now()).getTime();
long l1 = LocalDateTime.of(LocalDate.now(), LocalTime.now()).toInstant(ZoneOffset.ofHours(8)).getEpochSecond();
long l2 = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
System.out.println("LocalDateTime -> Long:  " + localDateTimeToLong);
LocalDateTime l = LocalDateTime.ofEpochSecond(1626421532132L,0,ZoneOffset.ofHours(8) )
LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(1627461973353), ZoneId.systemDefault());

// 丧心病狂的微妙记录:1635998054889000L
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String finalTime = sf.format(new Date(Long.parseLong(time)/1000));

public class TimeStampLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException,
            JsonProcessingException {
        if (!value.equals(TimeConstants.EMPTY_LOCAL_DATE_TIME)) {
            OffsetDateTime odt = OffsetDateTime.now(ZoneId.systemDefault());
            gen.writeNumber(value.toInstant(odt.getOffset()).toEpochMilli());
        }else {
            gen.writeNull();
        }
    }
}

public class TimeStampLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
    @Override
    public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException,
            JsonProcessingException {
        long timeStamp = Long.parseLong(p.getText());
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timeStamp), TimeZone.getDefault().toZoneId());
    }
}

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);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值