java8 Date/Time API 新的日期处理工具
接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Date/Time api 进行说明,新的日期时间工具全部都在 java.time 及其子包中。
新 Date/Time API 设计原则
Java 8日期/时间API是 JSR-310 规范的实现,它的目标是克服旧的日期/时间API实现中所有的缺陷,新的日期/时间API的一些设计原则如下:
- 不变性:新的日期/时间API中,所有的类都是不可变的,这种设计有利于并发编程。
- 关注点分离:新的API将人可读的日期时间和机器时间(unix timestamp)明确分离,它为日期(Date)、时间(Time)、日期时间(DateTime)、时间戳(unix timestamp)以及时区定义了不同的类。
- 清晰:在所有的类中,方法都被明确定义用以完成相同的行为。举个例子,要拿到当前实例我们可以使用now()方法,在所有的类中都定义了format()和parse()方法,而不是像以前那样专门有一个独立的类。为了更好的处理问题,所有的类都使用了工厂模式和策略模式,一旦你使用了其中某个类的方法,与其他类协同工作并不困难。
- 实用操作:所有新的日期/时间API类都实现了一系列方法用以完成通用的任务,如:加、减、格式化、解析、从日期/时间中提取单独部分等操作。
- 可扩展性:新的日期/时间API是工作在ISO-8601日历系统上的,但我们也可以将其应用在非IOS的日历上。
常用类及其使用
时间大致可以分为三个部分:日期、时间、时区;其中日期又细分为年、月、日;时间又细分为时、分、秒
一般机器时间用从 1970-01-01T00:00 到现在的秒数来表示时间; 这里纠正大部分人犯的一个错误概念,时间戳指的是秒数,而不是毫秒数。
几乎所有的时间对象都实现了 Temporal 接口,所以接口参数一般都是 Temporal
Instant: 表示时间线上的一个点,参考点是标准的Java纪元(epoch),即1970-01-01T00:00:00Z(1970年1月1日00:00 GMT)
LocalDate: 日期值对象如 2019-09-22
LocalTime:时间值对象如 21:25:36
LocalDateTime:日期+时间值对象
ZoneId:时区
ZonedDateTime:日期+时间+时区值对象
DateTimeFormatter:用于日期时间的格式化
Period:用于计算日期间隔
Duration:用于计算时间间隔
Instant 表示时间线上的一个点(瞬时)
// 测试执行一个 new 操作使用的时间(纳秒值)
Instant begin = Instant.now();
StreamMain streamMain = new StreamMain();
Instant end = Instant.now();
System.out.println(Duration.between(begin,end).toNanos());
LocalDate、LocalTime、LocalDateTime、ZonedDateTime 可以规为一组,用于表示时间的
// 可以使用 of 方法构建它们的实例,如下面创建了一个 2019-9-22 21:42:59 东八区 的时间对象
LocalDate localDate = LocalDate.of(2019, Month.SEPTEMBER, 22);
LocalTime localTime = LocalTime.of(21, 42, 59);
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
// 获取现在的时间,这是一个静态方法
LocalDate now = LocalDate.now();
// 每个实例可以获取它们的 part 信息,如获取年
int year = localDate.getYear();
// 可以修改 part 信息,这将返回一个新对象,如增加一年
LocalDate localDatePlus = localDate.plusYears(1);
// 设置 part 信息,也会返回新的对象,如设置为 2017 年
LocalDate localDateWithYear = localDate.withYear(2017);
// 比较两个日期 isAfter,isBefore
boolean after = localDate.isAfter(LocalDate.now());
// 格式化日期时间
// yyyy-MM-dd
System.out.println(now.format(DateTimeFormatter.ISO_DATE));
// yyyy-MM-ddTHH:mm:ss
System.out.println(now.format(DateTimeFormatter.ISO_DATE_TIME));
// yyyy-MM-dd HH:mm:ss
System.out.println(now.format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)));
// 日期解析
System.out.println(LocalDate.parse("2019-09-22"));
System.out.println(LocalDateTime.parse("2019-09-22T21:05:22"));
System.out.println(LocalDateTime.parse("2019-09-22 21:05:22",DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)));
ZoneId 用来操作时区,它提供了获取所有时区和本地时区的方法
ZoneId zoneId = ZoneId.systemDefault();
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
Period,Duration 可以视为一组,用于计算时间间隔
// 创建一个两周的间隔
Period periodWeeks = Period.ofWeeks(2);
// 一年三个月零二天的间隔
Period custom = Period.of(1, 3, 2);
// 一天的时长
Duration duration = Duration.ofDays(1);
// 计算2015/6/16 号到现在 2019/09/22 过了多久,它这个把间隔分到每个 part 了
LocalDate now = LocalDate.now();
LocalDate customDate = LocalDate.of(2015, 6, 16);
Period between = Period.between(customDate, now);
// 结果为 4:3:6 即过去了 4年3个月6天了
System.out.println(between.getYears()+":"+between.getMonths()+":"+between.getDays());
// 比较两个瞬时的时间间隔
Instant begin = Instant.now();
Instant end = Instant.now();
Duration.between(begin,end);
// 同样可以修改 part 信息和设置 part 信息,都是返回新的对象来表示设置过的值,原来的对象不变
Period plusDays = between.plusDays(1);
Period withDays = between.withDays(4);
与 Date,Calendar 的转换
虽然说,这个新的时间工具很好用,但如果不能与以前的旧的 api 兼容的话,一样是没有用的;还好新的工具类能很好的与以前的工具类进行相互转换。
通过 Instant做中间转换实现Date,Calendar 与 LocalDateTime,ZonedDateTime,LocalDate 的互相转换
// LocalDateTime 转 Date
Date localDateTimeDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
// LocalDateTime 转 Calendar
Calendar localDateTimeCalendar = GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
// Date 转 LocalDateTime
LocalDateTime dateLocalDateTime = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
// Calendar 转 LocalDateTime
LocalDateTime calendarLocalDateTime = LocalDateTime.ofInstant(calendar.toInstant(), ZoneOffset.systemDefault());
相关源码位置
https://gitee.com/sanri/example/tree/master/testjava8
一点小推广
创作不易,希望可以支持下我的开源软件,及我的小工具,欢迎来 gitee 点星,fork ,提 bug 。
Excel 通用导入导出,支持 Excel 公式
博客地址:https://blog.csdn.net/sanri1993/article/details/100601578
gitee:https://gitee.com/sanri/sanri-excel-poi
使用模板代码 ,从数据库生成代码 ,及一些项目中经常可以用到的小工具
博客地址:https://blog.csdn.net/sanri1993/article/details/98664034
gitee:https://gitee.com/sanri/sanri-tools-maven
java8 Date/Time API 新的日期处理工具的更多相关文章
- Java8简明学习之新时间日期API
由于历史原因,在之前的版本里无论Date还是Calendar都非常难用,尤其在涉及到日期计算方面,而且其中日期转换的类DateForamt还是非线程安全的.也正因为难用,一般项目里面都引入第三方的类库 ...
- Java8系列 (六) 新的日期和时间API
概述 在Java8之前, 我们一般都是使用 SimpleDateFormat 来解析和格式化日期时间, 但它是线程不安全的. @Test public void test() { SimpleDate ...
- Java 8——日期时间工具库(java.time)
一.前言 在介绍Java SE 8中新的日期时间库前,先了解下Java 8之前的日期时间工具的诟病. 在Java SE 8前,日期时间工具库在java.util包中,包括: java.util.Dat ...
- Java8学习笔记(九)--日期/时间(Date Time)API指南
Java 8日期/时间( Date/Time)API是开发人员最受追捧的变化之一,Java从一开始就没有对日期时间处理的一致性方法,因此日期/时间API也是除Java核心API以外另一项倍受欢迎的内容 ...
- (转载)Java8新的日期API LocalDate, LocalTime
前言 由于Java Date的各种问题,Java8推出了新的日期API,很受一拨人的追捧. 为什么我们需要新的Java日期/时间API? 在开始研究Java 8日期/时间API之前,让我们先来看一下为 ...
- java8新特性七-Date Time API
Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理. 在旧版的 Java 中,日期时间 API 存在诸多问题,其中有: 非线程安全 − java.ut ...
- Java8新特性--日期和时间API
如何正确处理时间 现实生活的世界里,时间是不断向前的,如果向前追溯时间的起点,可能是宇宙出生时,又或是是宇宙出现之前, 但肯定是我们目前无法找到的,我们不知道现在距离时间原点的精确距离.所以我们要表示 ...
- Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate
通过Java日期时间API系列7-----Jdk8中java.time包中的新的日期时间API类的优点,java8具有很多优点,现在网上查到的农历转换工具类都是基于jdk7及以前的类写的,下面使用ja ...
- Java8 新的日期和时间API(笔记)
LocalDate LocalTime Instant duration以及Period 使用LocalDate和LocalTime //2017-03-20 LocalDate date = Loc ...
随机推荐
- spring-boot-plus 常见问题解决 FAQ(十二)
spring-boot-plus 常见问题解决 FAQ 编译错误问题 log日志编译错误 编译提示log.info等日志错误 解决 检查是否安装lombok插件 idea安装lombok eclips ...
- 在Docker for Windows中运行GUI程序
Docker运行GUI原理 Docker目前大多应用在服务器领域,那么在Docker中可以运行GUI程序吗?怀着好奇心google了一番,还真有人写了一篇文章 running-gui-applicat ...
- 多渠道推广场景下,如何实现 App 用户增长的精准归因?
为了实现用户的快速增长,以推广 App 为目标的线上广告投放是很多平台获取新用户的重要方式.随道移动互联网的发展,现在 App 推广的渠道越来越丰富,除了 WAP 站点.第三方 App 之外,HTML ...
- SynchronousQueue队列程序的执行结果分析
public static void main(String[] args) throws Exception { /** * SynchronousQueue队列程序的执行结果分析 * Blocki ...
- C++的精度控制
#include <iostream> #include <iomanip> using namespace std; int main( void ) { const dou ...
- C#中的变量祥解
一.C#数据类型: A:值类型 值类型变量可以直接分配一个值,它是从System.ValueType派生而来,值类型直接包含数据,比如int,char,float,他们分别存储整型数据,字符,浮点数, ...
- Http请求传json数据中文乱码问题
业务场景:调easyui的dialog打开一个弹窗,传参是用json封装的,而且有中文,然后在极速模式是正常的,在ie11测试发现中文出现乱码了 var params = JSON.stringify ...
- JUC包实现的同步机制,原理以及简单用法总结
除了用Synchronized关键字修饰同步块,让线程获取某对象的锁实现多线程操作共享变量的同步外,还可以使用java.util.concurrent包.并且,juc包机制下的同步更灵活.juc包的所 ...
- 第10章 文档对象模型DOM 10.3 Element类型
Element 类型用于表现 XML或 HTML元素,提供了对元素标签名.子节点及特性的访问. 要访问元素的标签名,可以使用 nodeName 属性,也可以使用 tagName 属性:这两个属性会返回 ...
- Mybatis案例升级版——小案例大道理
纯Mybatis案例升级版——小案例大道理 前言: 这几天看了一本书<原则>,在上面看到了一句话叫“每个人都把自己眼界的局限当成世界的局限”,大学生是