百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

一文详解Java LocalDateTime

csdh11 2025-03-12 13:39 17 浏览

逃离“时光旋涡” —— 从一次Date对象的“时区迷航”说起

想象一下,你的项目正紧锣密鼓地推进,突然间,一个看似不起眼的日期处理任务,却引发了一场“完美风暴”。一个简单的任务需求:存储用户生日并按其所在时区显示。使用传统的java.util.Date,你以为只需寥寥数行代码即可轻松搞定,却不料踏入了一个布满陷阱的雷区。时区转换的微妙差异,导致存储的生日莫名其妙地“漂移”了一天;线程并发下的不稳定性,又让日期数据的准确性如履薄冰。这不仅仅是一个技术问题,更成为了影响用户体验的“阿喀琉斯之踵”。

Java 8引入了全新的日期时间API (java.time包),彻底革新了日期和时间的处理方式,其中LocalDateTimeLocalDateLocalTime三大类更是成为开发者手中的得力工具。遗憾的是,在java LTS版本已经发展到21的今天,Java 8引入的日期时间的类还未被大多数开发者熟练使用,本文会阐述这些又“新”又“旧”的类的基本用法,快来看看你都”学废“了吗?

LocalDateTime 时间与日期的完美融合

在Java 8中,LocalDateTime类作为java.time包的一员,标志着日期和时间处理的新篇章。它结合了LocalDate的日期信息和LocalTime的时间信息,提供了一个不含时区信息的日期时间表示方式,适用于那些只需要关注本地日期和时间,而不需要考虑时区差异的场景。

创建

LocalDateTime代表的是一个没有时区信息的日期和时间组合,适用于记录或显示本地日期和时间,比如会议安排、生日提醒等。创建LocalDateTime实例可以通过多种方式:

  • 当前日期时间:LocalDateTime now = LocalDateTime.now(); 获取当前系统默认时区的日期和时间。
  • 指定日期时间:LocalDateTime dt = LocalDateTime.of(2024, Month.JANUARY, 1, 12, 30); 创建特定的日期和时间。
  • 字符串解析:LocalDateTime parsed = LocalDateTime.parse("2024-01-01T12:30"); 从ISO 8601标准格式的字符串解析日期时间。

访问与修改

LocalDateTime提供了丰富的getter方法用于访问日期和时间的各个组成部分,如getYear(), getMonth(), getDayOfMonth(), getHour(), getMinute()等。同时,它还支持对日期时间进行调整:

  • 日期调整:如withDayOfMonth(15)将日期调整到当月的15号。
  • 时间调整:如plusHours(2)表示加上2小时。

操作与计算

LocalDateTime提供了加减日期或时间的方法,允许进行日期时间的计算:

  • 加减日期时间:LocalDateTime future = dt.plusDays(10); 计算10天后的日期时间。
  • 计算两个日期时间的差距:结合Duration或Period可以计算两个LocalDateTime之间的差异。

格式化与解析

为了适应不同的展示或存储需求,LocalDateTime支持自定义格式化和解析:

  • 格式化输出:DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formatted = dt.format(formatter); 格式化为指定样式。
  • 解析字符串:LocalDateTime fromString = LocalDateTime.parse("2023-01-01 12:30", formatter); 将格式化的字符串解析回LocalDateTime。

与时间相关的转换

虽然LocalDateTime不包含时区信息,但可以与其他包含时区的类(如ZonedDateTime)进行转换,以便在全球范围内使用:

  • 结合时区:通过ZonedDateTime zdt = dt.atZone(ZoneId.systemDefault()); 将本地日期时间转换为特定时区的日期时间。
  • 去除时区信息:从ZonedDateTime转换回LocalDateTime,可以使用zdt.toLocalDateTime()。

注意事项

  • 时区意识:虽然LocalDateTime不携带时区信息,但在处理跨国或跨时区的数据时,应考虑使用ZonedDateTime以避免混淆。
  • 不可变性:如同LocalDate和LocalTime,LocalDateTime也是不可变的,所有修改操作都会返回一个新的实例。
  • 线程安全:由于不可变性,LocalDateTime是线程安全的,适合在并发环境下使用。

LocalDate、LocalTime:日期与时间的纯粹表达

在Java 8中,除了全能的LocalDateTimejava.time包还为我们带来了两位专注于单一维度的勇士——LocalDateLocalTime。它们分别负责处理无时间的日期和无日期的时间信息,以其简洁而强大的设计,解决了众多日期时间处理中的痛点。接下来,让我们并肩探索LocalDateLocalTime的奥秘,了解它们如何在各自的领域内大放异彩。

LocalDate:纯粹的日期

LocalDate代表不含时间信息的日期,专注于年月日的管理,非常适合处理生日、纪念日、合同截止日期等场景。

  • 创建与获取:通过LocalDate.now()获取当前日期,或者使用LocalDate.of(2023, Month.JANUARY, 1)指定日期。
  • 日期操作:轻松进行日期的加减,如LocalDate tomorrow = today.plusDays(1)获取明天的日期。
  • 比较与判断:提供isBefore(), isAfter(), isEqual()等方法,方便比较日期先后。
  • 格式化与解析:与DateTimeFormatter结合,实现日期的自定义格式化输出和解析。

LocalTime:时间的精准表达

LocalTime专注于处理一天中的时间,没有日期信息,适用于记录营业时间、事件发生的具体时间点。

  • 初始化与获取:使用LocalTime.now()获取当前时间,或LocalTime.of(14, 30)指定具体时间。
  • 时间调整:通过plusHours(), minusMinutes()等方法,实现对时间的加减操作。
  • 比较与计算:提供方法来比较时间的早晚,以及计算两个时间点的差距,使用Duration来表示时间差。
  • 格式化与解析:同样支持与DateTimeFormatter的配合,进行时间的格式化输出和解析。

相互转换与应用场景

  • 相互结合:LocalDateTime实际上就是LocalDate和LocalTime的组合体,通过LocalDateTime.of(date, time)或各自类的atTime()、atDate()方法可以互相转换。
  • 专注单一维度:在处理特定场景时,单独使用LocalDate或LocalTime可以避免不必要的复杂性,提高代码的可读性和维护性。
  • 时区无关性:两者都不包含时区信息,适合处理与特定时区无关的日期或时间信息。

注意事项

  • 时区意识:虽然LocalDate和LocalTime不包含时区信息,但在处理跨越时区的数据时,应考虑使用ZonedDateTime。
  • 不可变性与线程安全:与LocalDateTime类似,LocalDate和LocalTime也是不可变类,所有修改操作返回新实例,保证了线程安全。
  • 精确计算:进行日期时间的加减操作时,应考虑使用Period和Duration来精确表达时间跨度。

LocalDateTime、LocalDate、LocalTime vs java.util.Date

相较于传统的java.util.Date类,在设计哲学、功能特性以及易用性上实现了显著的飞跃。以下是它们相对于Date类的主要优势:

明确的职责划分

  • LocalDateLocalTime分别专注于日期和时间的处理,这种分离使得模型更加清晰,避免了在单一对象中混合日期和时间信息可能导致的混淆。
  • LocalDateTime虽然综合了日期和时间,但其设计初衷就是为了清晰地处理含有日期和时间信息的场景,相比Date类的多功能混杂,使用起来更为直观。

不可变性与线程安全

  • 所有java.time类,包括LocalDateTime、LocalDate、LocalTime,均为不可变对象。这意味着一旦创建,它们的值就不会改变,这有助于在并发环境下保持数据的一致性,而Date类则是可变的,容易在多线程环境下引起数据竞争问题。

丰富的API设计

  • 新API提供了更丰富且直观的操作方法,如日期时间的加减、比较、格式化等,避免了Date类中繁琐且容易出错的日期时间计算。
  • 例如,LocalDate.plusDays()直接增加了天数,而Date类需要通过Calendar类间接操作,过程更为复杂。

时区处理的明确性

  • 虽然LocalDateTime、LocalDate、LocalTime本身不包含时区信息,但这实际上是为了清晰地区分本地时间与全球时间的概念。对于需要时区处理的场景,Java 8提供了ZonedDateTime类,它比Date类的时区处理更为灵活和精确。
  • 相比之下,Date类虽然包含时区信息,但处理时区问题时往往显得笨拙且不够明确。

ISO 8601标准遵循

  • LocalDateTime、LocalDate、LocalTime在格式化和解析上遵循ISO 8601国际标准,如YYYY-MM-DD和HH:mm:ss,这使得日期时间的字符串表示更加通用和标准化,便于跨系统和国际化应用。
  • 而Date类的默认字符串表示并不遵循任何标准格式,需要手动格式化和解析,增加了复杂度。

性能与精确性

  • java.time包采用了更高效的设计,尤其是对于日期时间的计算和存储,相比Date类在性能上有一定的提升。
  • 此外,新API提供了纳秒级的精度,而Date类的精度仅为毫秒级,对于需要极高时间精度的应用来说,这是一个显著的进步。

总结

可以看到,这些JDK8引入的Localxxx类,都可以让我们对日期和时间的处理更加准确和方便,虽然继续使用java.util.Date也在多数场景可以满足需求,让我想起一张远古的图

不过在不同的场景使用最适合的类和方法,尽量把代码写的简洁和优雅,才是一个程序猿不断追求的目标吧。

看到这里了,点个赞再走呗

原文:https://juejin.cn/post/7394345043131858970

作者:podongfeng

#记录我的2024#

相关推荐

教学楼里那种嵌着小石子的水磨石地面,是怎么整出来的? | 有趣的制造

今天的选题是之前小可爱「花凉」在后台发消息问的~看过以后念念不忘,满脑子都是小时候在教学楼冰冷地面上摔的跤,记不起来是不是在这种地面上磕掉的门牙...昨天发了预告后,有小可爱纷纷表示「就是这种地板,像...

教学楼里那种嵌着小石子的水磨石地面,是怎么整出来的?

话说有多少小可爱不想学习时,没事数着水磨石地面的小石子玩,然后互相评比哪颗石子最好看。到头来书又没有背完,课也没好好上,就怪地板有迷幻效果,扰乱了好好学习的坚定意志。(小编觉得即使换成瓷砖,你们也可能...

性能调优实战:Spring Boot 多线程处理SQL IN语句大量值的优化方案

环境:SpringBoot3.4.0...

RMAN备份监控及优化总结(rman全备份)

今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...

记Oracle中快速获取表及其各个字段注释的方法

简述java开发中,用过JPA的道友应该知道,我们可以通过写java代码自动生成对应的数据表;但这有个问题是,列名的注释并没有帮我们一起添加到数据库去,尤其在一些开发测试生产三个环境隔离的,就很不友好...

Oracle 数据库日常巡检之检查数据库cpu、I/O、内存性能

记录数据库的cpu使用、IO、内存等使用情况,使用vmstat,iostat,sar,top等命令进行信息收集并检查这些信息,判断资源使用情况。1.CPU使用情况:...

Oracle案例:ORA-00600: internal error code, arguments: 「4187」

本案例客户来自某省电信,alert日志大量的ORA-00600[4187]报错,已经影响到业务正常运行。...

MySQL索引失效的10大陷阱:从隐式类型转换到索引选择性全面优化

索引是MySQL性能优化的核心武器,但错误的使用场景可能让索引完全失效,导致查询性能断崖式下降。本文通过实际案例,深入剖析索引失效的典型场景及其底层原理,并提供可落地的解决方案。一、索引失效的核心原...

oracle查询语句执行计划分析(oracle如何查看sql执行计划)

1命令行开启配置#显示查询结果setautotraceon#不显示查询结果setautotracetraceonly2执行查询语句...

面试官:说说Oracle数据库result cache的原理是什么?

概述前面已经用实验给大家介绍了ResultCache相关内容,今天主要讨论一下Oracle11gResultCache的深层原理。从参数看,Oracle提供了ClientResultCac...

Oracle817 export 时ORA-06553和ORA-00904处理

现象:数据库版本8.1.7...

Oracle案例:一次gc buffer busy acquire诊断

本案例来自某客户两节点rac的一次生产故障,现象是大面积的gcbufferbusyacquire导致业务瘫痪。...

说文解字:“雪”字本身在造字时就很浪漫!

这是雪山的“雪”字。可是你知道吗?“雪”这个字其实和“山”是没有任何关系的。这个字下半部分“彐”并不是一座翻倒的山,而是一只手的意思。(凡是带“彐”的汉字,其实都和手有关。)“雪”字的商代甲骨文形状,...

应用最广的两类数据库的区别、优势对比、查询优化方法及案例实践

 1、通用数据库分类  1.1关系型数据库  关系型数据库是多个二维数据表的集合,数据以二维数据表的形式进行存储,数据表之间可以通过应用程序或者数据的主、外键建立特定的关联关系,让数据之间存在特定的...

【SQL】SQL 语法差异大全(PgSQL/MySQL/Oracle/TiDB/OceanBase)

以下是针对不同数据库系统的SQL语法差异总结,按功能分类展示:一、基础查询1.分页查询...