Java8 Date Time API

简介

Java8 带来了全新的处理日期和时间的方式。几乎所有人都有使用Java Date API痛苦的经历。因此有很多人切换到了Joda Time,但是Java8现在有了媲美Joda的时间API。在学习API前,先了解一下日期和时间的概念。Java日期遵循公历规则。表示时间和日期的类放在java.time包中。在这个包里比较重要的API有:

  • java.time.Period: 表示日期时期时间中的日期。表示日期部分的,年、月、日。例如:1年,两个月,5天。
  • java.time.Duration: 表示日期时间中的时间。 表示时间的,秒,纳秒。例如:5秒。
  • java.time.Instant: 表示时间线的一瞬间。保存的是UNIX时间戳的秒数,同时有另一个字段保存纳秒。
  • java.time.LocalDate: 保存日期时间中的日期,用年-月-日表示。不包含时区,是不可变类。
  • java.time.LocalTime: 保存日期时间中的时间,不包含时区。
  • java.time.LocalDateTime: 保存LocalDate和LocalTime,不包含时区。
  • java.time.ZoneDateTime: 保存LocalDateTIme,使用ZoneOffset保存时区信息。可以访问ZoneRule来转换本地时间。
  • java.time.ZoneOffset: 保存时区相对于UTC的位移,时区信息保存在ZoneId中。
  • java.time.OffsetDateTime: 通过位移来表示本地时间。这个类不包含时区规则。
创建本地日期
Instant now = Instant.now();
//2014-09-20T14:32:33.646Z

这个语句创建了一个新的时间实例。这个实例没有时区信息,如果打印这个实例将会打印UTC时间。

打印Unix时间戳
System.out.Println(now.getEpochSecond());
// prints 1411137153

Unix时间戳是从1970-01-01T00:00:00Z开始的。

Instant 加时间
Instant tomorrow = now.plus(1, ChronoUnit.DAYS);
// prints 2014-09-20T14:32:33.646Z

这个函数允许添加时间间隔。时间间隔可以是:NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, HALF_DAYS, DAYS。

Instant 减时间
Instant yesterday = now.minus(1,ChronoUnit.HALF_DAYS);
// prints 2014-09-20T03:38:33.860Z

这个minus函数允许从Instant中减时间,时间间隔同plus。

对比两个Instant
System.out.println(now.compareTo(tomorrow)); // prints -1

对比函数可以比较两个日期,如果参数在比较的Instant之后则返回-1,之前则返回1。

检查Instant是否在另一个Instant之后
System.out.println(now.isAfter(yesterday));// prints true
创建LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime); // prints 2014-09-28T13:01:40.556

注意,这个得到的是本地时区的时间

将LocalDateTime转换成其他时区时间
System.out.println(localDateTime.atZone(ZoneId.of("America/New_York")));
// prints 2014-09-28T13:07:31.207-04:00[America/New_York]

这个将会创建一个新的ZonedDateTime

从DateTime中获取星期
System.out.println(DayOfWeek.from(localDateTime));
// prints SUNDAY.
// (yes, i am working on a sunday :-( ) ))
从DateTime中获取一年中第几天
System.out.println(localDateTime.get(ChronoField.DAY_OF_YEAR));
// prints 271

其他的可以是MINUTE_OF_HOUR, MINUTE_OF_DAY, HOUR_OF_AMPM, HOUR_OF_DAY, AMPM_OF_DAY, DAY_OF_WEEK, DAY_OF_MONTH, DAY_OF_YEAR, MONTH_OF_YEAR, YEAR, OFFSET_SECONDS(UTC时间的位移)

从LocalDateTime中获取LocalDate
System.out.println(localDateTime.toLocalDate());
// prints 2014-09-29
从LocalDateTIme中获取LocalTime
System.out.println(localDateTime.toLocalTime());
// prints 22:26:30.146
通过年月日时分创建LocalDateTime
System.out.println(LocalDateTime.of(2014, 10, 1, 10, 0));
// prints 2014-10-01T10:00
通过解析字符串创建LocalDateTime
LocalDateTime parsedLocalDateTime = LocalDateTime.parse("2014-01-01T11:00");
创建另一个时区的LocalDateTime
System.out.println(LocalDateTime.now(ZoneId.of("UTC")));
// prints 2014-09-29T17:07:26.653 (the local timezone in UTC)
通过Instant和时区创建LocalDateTime
Instant now = Instant.now();
System.out.println(LocalDateTime.ofInstant(now, ZoneId.of("UTC")));
//2014-09-29T17:09:19.644
创建ZonedDateTime
ZonedDateTime zonedDateTime = ZonedDateTime.now();
//2014-09-29T22:41:24.908+05:30[Asia/Calcutta]
获取两个不同时间在不同单位之差
System.out.println(zonedDateTime.until(ZonedDateTime.parse("2014-09-29T22:41:00-10:00"), ChronoUnit.HOURS));
// prints the difference between the current zonedDateTime and the zonedatetime parsed from the above string
获取当前ZoneDateTime的位移
System.out.println(zonedDateTime.getOffset());
// prints the offset e.g. +10:00
使用DateTimeFormatter解析或者格式化时间
System.out.println(zonedDateTime.format(DateTimeFormatter.ofPattern("'The' dd 'day of' MMM 'in year' YYYY 'and zone is' z")));
// prints The 29 day of Sep in year 2014 and zone is IST
将ZoneDateTime更改时区

有两种方式可以完成这个任务,第一种不更改Instant更改时区,第二种更改时区不更改LocalTime

        System.out.println(zonedDateTime);
        System.out.println(zonedDateTime.toInstant());
        System.out.println(zonedDateTime.withZoneSameInstant(ZoneId.of("America/Chicago")));
        System.out.println(zonedDateTime.withZoneSameLocal(ZoneId.of("America/Chicago")));

        // prints 
        //System.out.println(zonedDateTime);
        //System.out.println(zonedDateTime.toInstant());
        //System.out.println(zonedDateTime.withZoneSameInstant(ZoneId.of("America/Chicago")));
        //System.out.println(zonedDateTime.withZoneSameLocal(ZoneId.of("America/Chicago")));

原文发布于微信公众号 - 代码拾遗(gh_8f61e8bcb1b1)

原文发表时间:2018-04-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏个人分享

Hive metastore源码阅读(一)

  不要问我为什么,因为爱,哈哈哈哈。。。进入正题,最近做项目顺带学习了下hive metastore的源码,进行下知识总结。

2801
来自专栏小樱的经验随笔

用Metaclass实现一个精简的ORM框架

存档: 1 # -*- coding: utf-8 -*- 2 class Field(object): 3 4 def __init__(s...

3205
来自专栏码匠的流水账

聊聊eureka client的serviceUrl

eureka-client-1.8.8-sources.jar!/com/netflix/discovery/DiscoveryClient.java

2721
来自专栏老马说编程

(95) Java 8的日期和时间API / 计算机程序的思维逻辑

本节继续探讨Java 8的新特性,主要是介绍Java 8对日期和时间API的增强,关于日期和时间,我们在之前已经介绍过两节了,32节介绍了Java 1.8以前的...

3748
来自专栏函数式编程语言及工具

Akka(8): 分布式运算:Remoting-远程查找式

  Akka是一种消息驱动运算模式,它实现跨JVM程序运算的方式是通过能跨JVM的消息系统来调动分布在不同JVM上ActorSystem中的Actor进行运算,...

4369
来自专栏Spark生态圈

[Spark SQL] 源码解析之Optimizer

optimizer 以及之后的模块都只会在触发了action操作后才会执行。优化器是用来将Resolved LogicalPlan转化为optimized Lo...

1042
来自专栏跟着阿笨一起玩NET

ASP.NET 存储过程操作

存储过程是存放在数据库服务器上的预先编译好的sql语句。使用存储过程,可以直接在数据库中存储并运行功能强大的任务。存储过程在第一应用程序执行时进行语法检查和编...

1551
来自专栏Java成神之路

Java企业微信开发_02_通讯录同步

       登录企业微信—>管理工具—>通讯录同步助手—>开启“API接口同步”  ; 开启后,即可看到通讯录密钥,也可设置通讯录API的权限:读取或者编辑通...

8852
来自专栏Java 技术分享

Ajax 案例之三级联动

3406
来自专栏JAVA后端开发

解决SpringMVC使用fastJson后Long类型丢失精度的问题

6793

扫码关注云+社区

领取腾讯云代金券