Java8 掌握Date与Java.time转换的核心思路,轻松解决各种时间转换问题

这篇具有很好参考价值的文章主要介绍了Java8 掌握Date与Java.time转换的核心思路,轻松解决各种时间转换问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。



Java8时区时间运用详解,2万字助你通关java.time包




转换核心思路

各种时间类的转换核心只有一个流程:时间类 -> 时间戳 -> 时间类

  • Date和Instant它们存储的都是时间戳信息
  • LocalDateTime、LocalDate、LocalTime、ZonedDateTime、OffsetDateTime、OffsetTime、Year等其它Java8时间类则是年、月、日、时、分、秒、纳秒中的部分值 + 时区或偏移量的组合

从转换角度来说,Date可以直接转为Instant,也可以根据时间戳直接转为其它时间类;Java8的其它时间类之间可以相互转换,也可以转为时间戳再转为Date或Instant。

所以本文有5种思路进行时间转换:

  1. Date转Instant
  2. Instant转Date
  3. Date转java8其它时间类
  4. Java8其它时间类转Date
  5. Java8的时间类互转




时间转换

1. Date —》 Instant

Date内部使用long fastTime存储整个时间戳System.currentTimeMillis(),而Instant则是使用秒long seconds和纳秒int nanos存储整个时间戳。所以它们可以直接互转。这里有一点要注意,时间戳记录的是UTC+0或GMT+0的时间,直接输出Date.toString()时,实际上会自动将GMT+0时间转为系统默认时区时间。

Date date = new Date();
// 1. Date兼容了Instant,可以直接转
Instant instant = date.toInstant(); 
// 2. 或通过时间戳初始化
Instant.ofEpochMilli(date.getTime());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// SimpleDateFormat中使用当前系统的默认时区输出时间,所以需要把时区转为UTC时区才能保证两者区时一致
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(simpleDateFormat.format(date));
System.out.println(instant);

输出时间:

2023-04-25 05:52:43
2023-04-25T05:52:43.246Z



2. Instant —》 Date

Instant与Date的互转方法类似,都是通过时间戳来创建实例:

Instant instant = Instant.now();
// 1. 构造方法转换
Date date = Date.from(instant);
// 2. 通过时间戳初始化
new Date(instant.toEpochMilli());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(simpleDateFormat.format(date));
System.out.println(instant);

输出时间:

2023-04-25 06:05:00
2023-04-25T06:05:00.882Z



3. Date —》 java8时间类

A. 通过转Instant的方式实现转换时间类
下面的时区ZoneId和时间偏移量ZoneOffset可以修改为系统的默认时区ZoneId.systemDefault()以显示和new Date().toString()一样的本地时间。

Date date = new Date();
Instant instant = date.toInstant();
// 1. 通过添加时区、偏移量信息直接转换
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("UTC"));
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC);

// 2. 通过构造方法
ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

B. 通过时间戳转时间类
正如一开始提到的核心转换思路,我们可以提供Date的时间戳(Instant同理),再将时间戳转为其它时间类:

long timestamp = date.getTime();
// 这里的计算就是Date转Instant,Instant转LocalDateTime的源代码实现方式
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(Math.floorDiv(timestamp, 1000), 
	(int) Math.floorMod(timestamp, 1000), ZoneOffset.UTC);
// 然后通过LocalDateTime转其它类
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
ZonedDateTime zonedDateTime1 = localDateTime.atZone(ZoneId.of("UTC"));
OffsetDateTime offsetDateTime1 = localDateTime.atOffset(ZoneOffset.UTC);

C. 通过字符串格式化转换
这种方式比较取巧,不过却很有用,需要注意的点是:LocalDateTime、ZonedDateTime和OffsetDateTime必须提供偏移量信息(或时区信息)。

String pattern = "yyyy-MM-dd HH:mm:ss X";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String format = simpleDateFormat.format(date);
LocalDateTime.parse(format, dateTimeFormatter);
OffsetDateTime.parse(format, dateTimeFormatter);
ZonedDateTime.parse(format, dateTimeFormatter);

DateTimeFormatter中关于时间格式化中字母代表的匹配含义(部分):

  • V:时区ID,America/Los_Angeles; Z; -08:30
  • z:时区名称或简称, Pacific Standard Time; PST
  • Z:时间偏移量,无指定时区,仅代表偏移量范围,+0000; -0800; -08:00;
  • x:时间偏移量,无指定时区,仅代表偏移量范围,+0000; -08; -0830; -08:30; -083015; -08:30:15;
  • X:世界时(UTC-GMT-UT,取决于时间类支持哪一个世界时)的时间偏移量,Z; -08; -0830; -08:30; -083015; -08:30:15;
  • O:带时区的时间偏移量,GMT+8; GMT+08:00; UTC-08:00;

SimpleDateFormat中关于时间格式化中字母代表的匹配含义(部分):

  • V:无
  • z:时区名称或简称或时区偏移量, Pacific Standard Time; PST;GMT-08:00
  • Z:时间偏移量,无指定时区,仅代表偏移量范围,+0000; -0800; -08:00;
  • x:无
  • X:时间偏移量,无指定时区,仅代表偏移量范围,-08; -0800; -08:00
  • O:无

对比上述三种方法可以看到,Date要转其它时间类,还是通过先转Instant -> 再转其它时间类的方式更方便。



4. Java8时间类 —》 Date

使用Date转java8其它时间类的逆方向转换即可。

初始化时间:

LocalDateTime localDateTime = LocalDateTime.now();
OffsetDateTime offsetDateTime = OffsetDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();

A. 通过转Instant的方式实现转换Date

转Instant,再转Date

Instant instant = localDateTime.toInstant(ZoneOffset.ofHours(8));
offsetDateTime.toInstant();
zonedDateTime.toInstant();
Date date = Date.from(instant);
// 输出
System.out.println(localDateTime);
System.out.println(offsetDateTime);
System.out.println(zonedDateTime);
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));

输出时间:

2023-04-25T15:18:53.585
2023-04-25T15:18:53.586+08:00
2023-04-25T15:18:53.586+08:00[Asia/Shanghai]
2023-04-25 15:18:53

B. 通过时间戳转Date
localDateTime等时间类可以获取时间的秒级时间戳,所以可以根据这个时间戳直接转为Date。这种转换会损失纳毫秒精度,如果对精度有要求的话,还是得通过转Instant然后调用方法toEpochMilli()来实现。

long epochSecond = localDateTime.toEpochSecond(ZoneOffset.ofHours(8));
offsetDateTime.toEpochSecond();
zonedDateTime.toEpochSecond();
Date date1 = new Date(epochSecond * 1000L);

C. 通过字符串格式化转换
由于Java8中的时间类具备不同的属性(时区、偏移量等),所以通过时间字符串格式化时,LocalDateTime、OffsetDateTime和ZonedDateTime的格式化字符串有所不同。这一点与Date转这些时间类不同,需要在实际转换时注意。

String local = "yyyy-MM-dd HH:mm:ss";
String offset = "yyyy-MM-dd HH:mm:ss X";
String zone = "yyyy-MM-dd HH:mm:ss z";
System.out.println(new SimpleDateFormat(local).parse(DateTimeFormatter.ofPattern(local).format(localDateTime)));
System.out.println(new SimpleDateFormat(offset).parse(DateTimeFormatter.ofPattern(offset).format(offsetDateTime)));
System.out.println(new SimpleDateFormat(zone).parse(DateTimeFormatter.ofPattern(zone).format(zonedDateTime)));

输出时间如下:

Tue Apr 25 16:18:37 CST 2023
Tue Apr 25 16:18:37 CST 2023
Tue Apr 25 16:18:37 CST 2023



5. Java8时间类互转

下面的转换将会提供每一种时间类支持的所有转换情况,包括构造方法、实例对象方法。

A. Instant

Instant instant = Instant.now();
// 通过实例对象转换
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("UTC"));
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC);
// 通过构造方法转换
ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"));
OffsetDateTime.ofInstant(instant, ZoneOffset.UTC);
LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

B. LocalDateTime
转换OffsetDateTime和ZonedDateTime时,没有toXX方法、且不能使用from(TemporalAccessor temporal)构造方法实例化,因为LocalDateTime没有时区和偏移量信息。

LocalDateTime localDateTime = LocalDateTime.now();
ZoneOffset zoneOffset = ZoneOffset.ofHours(8);
// 通过实例对象转换
Instant instant = localDateTime.toInstant(zoneOffset);
LocalDate localDate = localDateTime.toLocalDate();
LocalTime localTime = localDateTime.toLocalTime();
ZonedDateTime zonedDateTime = localDateTime.atZone(zoneOffset);
OffsetDateTime offsetDateTime = localDateTime.atOffset(zoneOffset);
// 通过构造方法转换
Instant.ofEpochSecond(localDateTime.toEpochSecond(zoneOffset));
LocalDate.from(localDateTime);
LocalTime.from(localDateTime);
OffsetDateTime.of(localDateTime, zoneOffset);
ZonedDateTime.of(localDateTime, zoneOffset);

C. OffsetDateTime
OffsetDateTime和ZonedDateTime的转换相同,使用toXXX直接转为其它时间类,使用其它时间类的from方法复制其时间信息。

OffsetDateTime offsetDateTime = OffsetDateTime.now();
// 通过实例对象转换
Instant instant = offsetDateTime.toInstant();
OffsetTime offsetTime = offsetDateTime.toOffsetTime();
LocalDate localDate = offsetDateTime.toLocalDate();
LocalTime localTime = offsetDateTime.toLocalTime();
LocalDateTime localDateTime = offsetDateTime.toLocalDateTime();
ZonedDateTime zonedDateTime = offsetDateTime.toZonedDateTime();
// 通过构造方法转换
Instant.from(offsetDateTime);
OffsetTime.from(offsetDateTime);
LocalDate.from(offsetDateTime);
LocalTime.from(offsetDateTime);
LocalDateTime.from(offsetDateTime);
ZonedDateTime.from(offsetDateTime);

D.ZonedDateTime文章来源地址https://www.toymoban.com/news/detail-430702.html

ZonedDateTime zonedDateTime = ZonedDateTime.now();
// 通过实例对象转换
Instant instant = zonedDateTime.toInstant();
LocalDate localDate = zonedDateTime.toLocalDate();
LocalTime localTime = zonedDateTime.toLocalTime();
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();
// 通过构造方法转换
Instant.from(zonedDateTime);
OffsetTime.from(zonedDateTime);
OffsetDateTime.from(zonedDateTime);
LocalDate.from(zonedDateTime);
LocalTime.from(zonedDateTime);
LocalDateTime.from(zonedDateTime);

到了这里,关于Java8 掌握Date与Java.time转换的核心思路,轻松解决各种时间转换问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决报错InvalidDefinitionException Java 8 date/time type LocalDateTime not supported by default jsr310

    最近新开了一个测试项目,使用了Java8的LocalDateTime替换了之前使用的Date类。接口返回结果时,抛出了序列化异常: spring boot:2.5.1 jackson-databind:2.12.3 1. 使用@JsonSerialize + @JsonDeserialize注解 pom加上这两个注解的依赖 在使用LocalDateTime的属性上添加这两个序列化反序列化注解:

    2024年02月16日
    浏览(50)
  • 从零开始学习JavaScript:轻松掌握编程语言的核心技能②

    🏘️🏘️个人简介:以山河作礼。 🎖️🎖️: Python领域新星创作者,CSDN实力新星认证,阿里云社区专家博主 🎁🎁:Web全栈开发专栏:《Web全栈开发》免费专栏,欢迎阅读! 📜 📜 JavaScript 函数是一段可以被重复调用的代码块。它可以接收输入参数,处理这些参数,然后返

    2024年02月08日
    浏览(68)
  • 从零开始学习JavaScript:轻松掌握编程语言的核心技能③

    🏘️🏘️个人简介:以山河作礼。 🎖️🎖️: Python领域新星创作者,CSDN实力新星认证,阿里云社区专家博主 🎁🎁:Web全栈开发专栏:《Web全栈开发》免费专栏,欢迎阅读! 📑📑 JavaScript中的if…else语句是一种条件语句,用于在满足特定条件时执行不同的代码块 。 📌

    2024年02月08日
    浏览(67)
  • 从零开始学习JavaScript:轻松掌握编程语言的核心技能⑤

    🏘️🏘️个人简介:以山河作礼。 🎖️🎖️: Python领域新星创作者,CSDN实力新星认证,阿里云社区专家博主 🎁🎁:Web全栈开发专栏:《Web全栈开发》免费专栏,欢迎阅读! 📑📑 在 JavaScript 中,函数可以通过 function 来定义 。 📌 函数定义的一般语法如下: 其中,

    2024年02月08日
    浏览(68)
  • 从零开始学习JavaScript:轻松掌握编程语言的核心技能④

    🏘️🏘️个人简介:以山河作礼。 🎖️🎖️: Python领域新星创作者,CSDN实力新星认证,阿里云社区专家博主 🎁🎁:Web全栈开发专栏:《Web全栈开发》免费专栏,欢迎阅读! 📌 JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证。 表单数据经常需

    2024年02月08日
    浏览(57)
  • 从零开始学习JavaScript:轻松掌握编程语言的核心技能①

    🏘️🏘️个人简介:以山河作礼。 🎖️🎖️: Python领域新星创作者,CSDN实力新星认证,阿里云社区专家博主 🎁🎁:Web全栈开发专栏:《Web全栈开发》免费专栏,欢迎阅读! 📜📜 JavaScript 是一种脚本语言,用于在 Web 页面上执行交互式操作和动态效果 。它最初由 Brendan

    2024年02月07日
    浏览(68)
  • 还在用Calendar操作Date?Java8都弃用了,还不知道它的这款强大的工具吗?

    在过去的Java版本中,日期和时间的处理主要依赖于 java.util.Date 和 java.util.Calendar 类,然而随着业务系统的复杂以及技术层面的提升,这些传统的日期时间类暴露出了若干显著的不足之处。随着 Java8 的发布,其引入了一套全新的日期时间API,彻底改变了我们处理日期和时间的

    2024年03月18日
    浏览(45)
  • Java 8 date/time type `java.time.LocalDateTime` not supported by default:日期序列化问题

    解决办法一:将实体类中的LocalDateTime转为Date类型 解决办法二: 通过注解指定 配置全局 解决办法三: 用阿里的FastJson替换ObjectMapper

    2024年02月12日
    浏览(43)
  • 视频批量高效剪辑,支持将视频文件转换为音频文件,轻松掌握视频格式

    在数字化时代,视频内容日益丰富,管理和编辑这些视频变得愈发重要。然而,传统的视频剪辑软件往往操作复杂,难以满足高效批量处理的需求。现在,一款全新的视频批量剪辑神器应运而生,它支持将视频文件一键转换为音频文件,同时轻松掌握各种视频格式,让你的视

    2024年04月14日
    浏览(61)
  • springboot~统一处理日期请求参数java.utils.Date和java.time.LocalDate

    日期类型的参数在从前端通过url参数传递到后端时,它会被进行格式化,如果格式化失败会出现400的错误,像日期格式默认会使用yyyy/MM/dd的格式,如果希望自己去个性化配置,我们可以通过实现WebMvcConfigurer接口的addFormatters方法来完成。 DateTimeFormatterRegistrar 实例的 setTimeFor

    2024年02月06日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包