还在用Java Date,新姿势了解下?

从JDK1.8开始,Java提供了java.time包,该包用于描述ISO日历系统中的日期和时间。通过该包下的类可以实现分别访问日期、时间和时间戳等对象。 不像java.util.Date, 一个类包含日期和时间所有信息。比如你可以使用LocalDate对象来表示日期,使用LocalTime对象表示时间,用LoalDateTime对象表示日期时间。

概述

​ 从JDK1.8开始,Java增加了java.time包,此包下定义了代表日期时间概念的类,包括瞬间、持续时间、日期、时间、时区和周期。 这些类基于ISO日历系统定义的,他们都是不可变的且线程安全的。java.time包中定义了很多用于描述时间的类,这里我们选择其中一部分进行讲解,首先我们看下他们的类关系图,如下所示:

在这里插入图片描述

  • Temporal:日期、时间和偏移时间的接口类,它定义了Temporal接口对象的加减运算、创建对象等方法。
  • TemporalAccessor:定义了访问Temporal对象的方法,比如获取日期对象中的年、月、日属性。
  • TemporalAdjuster:修改Temporal的接口。
  • LocalDate:用于表示日期,比如“2022-3-30”。
  • LocalTime:用于表示时间,比如“16:15:45.326657”。
  • LocalDateTime:用于表示日期和时间,但不包含时区,时间精确到纳秒,比如“2022-03-30T16:15:45.836657”。
  • ZoneId:用于表示时区ID,有三种表达形式:
    • 以字符’ Z’或者’+’、’-‘开头,其中’Z’表示0时区,’+‘表示东时区,’-'表示西时区,比如"+8"表示东八区;
    • 以’UTC’、‘GMT’、'UT’为前缀,加上偏移时间,比如"UTC+8"表示东八区;
    • 基于地区定义的ID,比如"Asia/Shanghai";
  • Instant:用于表示某个瞬间,可以理解为时间戳;
  • Clock:用于使用时区访问瞬间、日期和时间的时钟对象;Clock是抽象类,有四个嵌套子类:FixedClock、OffsetClock、SystemClock、TickClock。
  • ZonedDateTime:用于表示包含时区信息的日期时间类。LocalDateTime不存储时区信息,如果想要对象保存时区信息,那么可该用ZonedDateTime对象。从上面的类图也可看出该类依赖LocalDateTime、ZoneId和ZoneOffset;
  • ZoneOffset:用于描述与格林威治/UTC 的时区偏移量,比如我国的时区偏移量为 “+08:00”。

接下来我们来了解下其中的几个类,他们分别是LocalDate, LocalTime和LocalDateTime(备注,文中的代码是基于JDK11,有部分方法在JDK1.8上未定义)。

LocalDate

​ LocalDate 是用于描述ISO-8601日历系统中日期,但不包括时区时间信息。LocalDate 正如其名,此类不存储时间或时区,也就是说不能通过LocalDate对象获取时间或者时区;它只用于描述日期,通常为“年-月-日”。通过LocalDate提供的实例方法也可以访问其他日期字段,比如一年中的某一天、一周中的某一天和一年中某一周。LocalDate对象是不可以变对象,正因如此它也是线程安全的。

常见方法

now()

now()有三个重载方法,他们最终是通过ofInstant方法实现创建LocalDate对象,具体细节在此不展开,感兴趣的同学可以看下源码,我们主要看下这三个重载方法的使用。

private void localDate() {
   
    //不指定时区,则使用系统默认时区
    LocalDate localDate = LocalDate.now();
    Log.print("localDate: " + localDate);
  
    //通过Clock对象创建LocalDate,Clock对象指定的时区为西10区,
    LocalDate localDateByClock = LocalDate.now(Clock.system(ZoneId.of("UTC-10")));
    Log.print("localeDate by clock: " + localDateByClock);
  
    //通过ZoneId对象创建LocalDate,时区为西10区;
    LocalDate localDateByZoneId = LocalDate.now(ZoneId.of("UT-9"));
    Log.print("localeDate by zone id: " + localDateByZoneId);
}

输出结果如下:

localDate: 2022-03-27
localeDate by clock: 2022-03-26
localeDate by zone id: 2022-03-27

代码运行的时间是2022年3月27日17:30,所在的时区为“UTC+8”,所以第一行打印是"2022-03-27",localDateByClock对象指定的时区为“UTC-10”,所以与localDate所在的时区相差18个小时,所以第二行打印为"2022-03-26",localDateByZoneId 指定的时区与localDate所在的时区相差17个小时,所以第三行打印为"2022-03-27"。(备注,文中的Log.print()是对系统打印的简单封装)

ofxxx()

LocalDate有多个ofxxx()方法,我们通过例子来看下其中的几个:

private void localeDateOf() {
   
    //of(int year, int month, int dayOfMonth)通过指定整数年月日创建LocalDate对象
    LocalDate localDate = LocalDate.of(2022, 2, 28);
    Log.print("localDate: " + localDate);
  
    //of(int year, Month month, int dayOfMonth)通过整数年日和Month对象创建LocalDate对象。
    LocalDate localDateOf = LocalDate.of(2022, Month.FEBRUARY, 28);
    Log.print("localDateOf: " + localDateOf);
  
    //ofYearDay(int year, int dayOfYear)通过年和一年中的第几天创建LocalDate对象
    LocalDate localDateYearOfDay = LocalDate.ofYearDay(2022, 60);
    //2020年为闰年,所以对应的日期为2020-02-29
    LocalDate localDate2020OfDay = LocalDate.ofYearDay(2020, 60);
    Log.print("localDateYearOfDay: " + localDateYearOfDay + ", localDate2020OfDay: " + localDate2020OfDay);
  
    //通过Instant和ZoneId(UTC-10)对象创建LocalDate对象,当前时间是17:30,
    //所以创建的LocalDate对应的日期是2022-03-26
    LocalDate localDateByInstant = LocalDate.ofInstant(Instant.now(), ZoneId.of("UTC-10"));
    //采用系统默认ZoneID(UTC+8)创建LocalDate对象
    LocalDate localDateByInstantDefaultZoneDate = LocalDate.ofInstant(Instant.now(),
                                                                      ZoneId.systemDefault());
    Log.print("localDateByInstant: " + localDateByInstant 
              + ", localDateByInstantDefaultZoneDate: " + localDateByInstantDefaultZoneDate);
}
localDate: 2022-02-28
localDateOf: 2022-02-28
localDateYearOfDay: 2022-03-01, localDate2020OfDay: 2020-02-29
localDateByInstant: 2022-03-26, localDateByInstantDefaultZoneDate: 2022-03-27
运算

​ 运算包括对年、月、周、日的加减操作,对LocalDate对象的加减操作返回的是LocalDate对象的副本,LocalDate对象本身不会发生变化,因为LocalDate对象是不可变的。具体看实际例子

/**
 * LocalDate 年、月、周、日的加减运算
 */
private void localDateOperation() {
   
    LocalDate localDate = LocalDate.now
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值