Java8学习笔记:LocalDateTime、Instant 和 OffsetDateTime 相互转换

本文主要是介绍Java8学习笔记:LocalDateTime、Instant 和 OffsetDateTime 相互转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

环境

Java 1.8+
IDEA:2019.2.4

前言

最近在写接口 由遇到了LocalDate或者LocalDateTimeOffsetDatetime的问题;
遇到这个时,总是有点懵;今天花时间总结下

Java8中时间api

推荐使用的是:

LocalDate
LocalTime
Insant
Duration
Period

OffsetDatetime 转 字符串

String DATE_TIME_SECOND_STRING = "yyyy-MM-dd HH:mm:ss";
OffsetDateTime offsetDateTime = 2019-10-10T00:00+08:00
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_SECOND_STRING);
String result = dateTimeFormatter.format(offsetDateTime);

offsetDateTime 在程序中的值,如下图:
在这里插入图片描述

字符串 转 OffsetDatetime

String DATE_TIME_SECOND_STRING = "yyyy-MM-dd HH:mm:ss";
String value = "2019-10-10 00:00:00";
// 方法一
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_SECOND_STRING);
LocalDateTime parse1 = LocalDateTime.parse(value, dateTimeFormatter);
// 结果
OffsetDateTime offsetDateTime = ZonedDateTime.of(parse1, ZoneId.systemDefault()).toOffsetDateTime();
// 方法二
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_SECOND_STRING)
.withZone(ZoneId.systemDefault());
// 结果
OffsetDateTime offsetDateTime = ZonedDateTime.parse(value, dateTimeFormatter).toOffsetDateTime();

只有年份 yyyy-MM-dd的情况

String value = "2019-10-10";
// 解析的pattern也要做出相应调整
String DATE_SECOND_STRING = "yyyy-MM-dd";
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME_SECOND_STRING);
// 这个地方特别注意,使用LocalDateTime会报错的
LocalDate parse = LocalDate.parse(value, dateTimeFormatter);
OffsetDateTime offsetDateTime = 
ZonedDateTime.of(LocalDateTime.of(parse, LocalTime.MIN), ZoneId.systemDefault()).toOffsetDateTime();

LocalDatetime 转 OffsetDatetime

假设我们有:

LocalDateTime localDateTime = LocalDateTime.now();

按照OffsetDateTime提供的方法:

OffsetDateTime of(LocalDateTime dateTime, ZoneOffset offset)

即我们还需要一个ZoneOffset

ZoneOffset表示的是格林威治/UTC的时区偏移量,例如+02:00

所以我们可以这么用:

OffsetDateTime.of(localDateTime, ZoneOffset.of("+8")))
//  或者
OffsetDateTime.of(localDateTime, ZoneOffset.ofHours(8))

LocalDate 转 OffsetDatetime

由上面可知,我们知道LocalDatetimeOffsetDatetime的方法

那么我们可以先将LocalDate转成LocalDatetime;

LocalDate parse = LocalDate.parse(value, dateTimeFormatter);
// 先将LocalDate转为LocalDateTime
LocalDateTime localDateTime = LocalDateTime.of(parse, LocalTime.MIN);
OffsetDateTime offsetDateTime = 
ZonedDateTime.of(localDateTime, ZoneId.systemDefault()).toOffsetDateTime();

LocalDateTime 转 Instant

根据LocalDateTime自带的方法:

localDateTime.toInstant(ZoneOffset.of(“+8”));
// 或者
localDateTime.toInstant(ZoneOffset.ofHours(8));

但如果使用如下方式:

Instant.ofEpochSecond(localDateTime.toEpochSecond(ZoneOffset.of("+8")));

上面这句的结果:年月日是对滴,时间的话就是伦敦时间了。

因为toEpochSecond只控制到了秒,而不是毫秒;

Instant 转 OffsetDateTime

由于Instant类中没有提供,所以就去OffsetDateTime里面找:

OffsetDateTime.ofInstant(instant, ZoneId.systemDefault())

出于这样的思路,我们LocalDateTimeOffsetDatetime,就多了一条路,

我们先LocalDateTimeInstant,然后再InstantLocalDateTime,当然这有点多此一举。

LocalDateTime、Instant 转 毫秒

看了LocalDateTime后才知道,其只提供了转的方法,并没有提供转毫秒的方法。

转秒的:

localDateTime.toEpochSecond(ZoneOffset.of("+8"))

如何转毫秒呢?

得借用Instant类中的toEpochMilli方法:

localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli()

这样就得到了毫秒;

关系图

这幅图来自于Java8实战这本书籍

在这里插入图片描述

从上面的图中我们可以看出,LocalDateTime,并不能表示我们人类世界中完整的时间,而ZonedDateTime可以。

而且上面的转换中我们可以知道,LocalDateTimeInstant或者OffsetDatetime都是需要加上偏移时区的(ZoneOffset)。

所以可以得出 OffsetDatetimeInstant也是可以表示人类世界中完整的时间的,和ZoneDateTime是等效的。

那么区别呢?

OffsetDatetime、Instant和 ZoneDateTime区别

先看下网上的答案:

OffsetDateTime, ZonedDateTime and Instant all store an instant on the time-line to nanosecond precision. Instant is the simplest, simply representing the instant. OffsetDateTime adds to the instant the offset from UTC/Greenwich, which allows the local date-time to be obtained. ZonedDateTime adds full time-zone rules.

OffsetDateTime ,ZonedDateTime 和 Instant 都会在时间线上存储一个纳秒级精度。 Instant 是最简单的,只需代表instant。 OffsetDateTime 添加到UTC / Greenwich的偏移瞬间,这允许获得本地日期时间。 ZonedDateTime 添加完整的时区规则。

Thus the difference between OffsetDateTime and ZonedDateTime is that the latter includes the rules that cover daylight saving time adjustments.

因此 OffsetDateTime 和之间的区别ZonedDateTime 是后者包括涵盖夏令时调整的规则。


个人以为:

首先Instant是给机器看的类,所以我觉得,他肯定能表示世界完整时间。
重点就是OffsetDatetimeZoneDateTime
就我上面的例子而言,我觉得没什么区别。
但根据老外的言论,那就是是否包含夏令营规则的区别

最后顺便记录一个老外的提问:

OffsetDateTime should be used when writing date to database, but I don’t get why.

当将日期写入数据库时,为什么要使用OffsetDatetime

答复:

One reason is that dates with local time offsets always represent the same instants in time, and therefore have a stable ordering. By contrast, the meaning of dates with full timezone information is unstable in the face of adjustments to the rules for the respective timezones. (And these do happen…)


Dates whose meaning / ordering is unstable are problematic if (for example) you create a database index on a field the date.

一个原因是具有局部时间偏移的日期总是代表相同的时刻,因此具有稳定的排序。 相比之下,面对对各个时区的规则进行调整,具有全时区信息的日期的含义是不稳定的。 (这些确实发生了…)

如果(例如)在日期的字段上创建数据库索引,则其含义/排序不稳定的日期会出现问题。

设置23:59:59 和 00:00:00

// 设置 23:59:59
OffsetDateTime  endDateTime = endDateTime.with(LocalTime.MAX);
// 设置 00:00:00
OffsetDateTime  endDateTime = endDateTime.with(LocalTime.MIN);

参考地址:

https://stackoverflow.com/questions/30234594/whats-the-difference-between-java-8-zoneddatetime-and-offsetdatetime

https://www.yiibai.com/javatime/javatime_zoneoffset.html

https://blog.csdn.net/hspingcc/article/details/73332252


最近发现一篇写的很好的文章:

LocalDateTime、OffsetDateTime、ZonedDateTime互转,这一篇绝对喂饱你

这里摘抄里面一段总结:

OffsetDateTime和ZonedDateTime的区别

LocalDateTime、OffsetDateTime、ZonedDateTime这三个哥们,LocalDateTime好理解,一般都没有异议。但是很多同学对OffsetDateTime和ZonedDateTime傻傻分不清,这里说说它俩的区别。

  1. OffsetDateTime = LocalDateTime + 偏移量ZoneOffset;ZonedDateTime = LocalDateTime + 时区ZoneId
  2. OffsetDateTime可以随意设置偏移值,但ZonedDateTime无法自由设置偏移值,因为此值是由时区ZoneId控制的
  3. OffsetDateTime无法支持夏令时等规则,但ZonedDateTime可以很好的处理夏令时调整
  4. OffsetDateTime得益于不变性一般用于数据库存储、网络通信;而ZonedDateTime得益于其时区特性,一般在指定时区里显示时间非常方便,无需认为干预规则
  5. OffsetDateTime代表一个瞬时值,而ZonedDateTime的值是不稳定的,需要在某个瞬时根据当时的规则计算出来偏移量从而确定实际值

总的来说,OffsetDateTime和ZonedDateTime的区别主要在于ZoneOffset和ZoneId的区别。如果你只是用来传递数据,请使用OffsetDateTime,若你想在特定时区里做时间显示那么请务必使用ZonedDateTime。

这篇关于Java8学习笔记:LocalDateTime、Instant 和 OffsetDateTime 相互转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1112118

相关文章

java对接海康摄像头的完整步骤记录

《java对接海康摄像头的完整步骤记录》在Java中调用海康威视摄像头通常需要使用海康威视提供的SDK,下面这篇文章主要给大家介绍了关于java对接海康摄像头的完整步骤,文中通过代码介绍的非常详细,需... 目录一、开发环境准备二、实现Java调用设备接口(一)加载动态链接库(二)结构体、接口重定义1.类型

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Java Multimap实现类与操作的具体示例

《JavaMultimap实现类与操作的具体示例》Multimap出现在Google的Guava库中,它为Java提供了更加灵活的集合操作,:本文主要介绍JavaMultimap实现类与操作的... 目录一、Multimap 概述Multimap 主要特点:二、Multimap 实现类1. ListMult

Java中常见队列举例详解(非线程安全)

《Java中常见队列举例详解(非线程安全)》队列用于模拟队列这种数据结构,队列通常是指先进先出的容器,:本文主要介绍Java中常见队列(非线程安全)的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一.队列定义 二.常见接口 三.常见实现类3.1 ArrayDeque3.1.1 实现原理3.1.2

SpringBoot整合Apache Flink的详细指南

《SpringBoot整合ApacheFlink的详细指南》这篇文章主要为大家详细介绍了SpringBoot整合ApacheFlink的详细过程,涵盖环境准备,依赖配置,代码实现及运行步骤,感兴趣的... 目录1. 背景与目标2. 环境准备2.1 开发工具2.2 技术版本3. 创建 Spring Boot

springboot加载不到nacos配置中心的配置问题处理

《springboot加载不到nacos配置中心的配置问题处理》:本文主要介绍springboot加载不到nacos配置中心的配置问题处理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录springboot加载不到nacos配置中心的配置两种可能Spring Boot 版本Nacos

Java反射实现多属性去重与分组功能

《Java反射实现多属性去重与分组功能》在Java开发中,​​List是一种非常常用的数据结构,通常我们会遇到这样的问题:如何处理​​List​​​中的相同字段?无论是去重还是分组,合理的操作可以提高... 目录一、开发环境与基础组件准备1.环境配置:2. 代码结构说明:二、基础反射工具:BeanUtils

在Java中将XLS转换为XLSX的实现方案

《在Java中将XLS转换为XLSX的实现方案》在本文中,我们将探讨传统ExcelXLS格式与现代XLSX格式的结构差异,并为Java开发者提供转换方案,通过了解底层原理、性能优势及实用工具,您将掌握... 目录为什么升级XLS到XLSX值得投入?实际转换过程解析推荐技术方案对比Apache POI实现编程

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co