8.Java 8 日期时间处理:从 Date 的崩溃到 LocalDate 的优雅自救
一、被 Date 逼疯的程序员:那些年踩过的坑
还记得刚学 Java 时被Date支配的恐惧吗?
- 想获取 "2023 年 10 月 1 日"?new Date(2023, 9, 1)—— 等等,为什么月份是 9?哦对,Java 的月份从 0 开始,像极了程序员的发际线,永远比预期少一截。
- 想格式化日期?SimpleDateFormat看似万能,实则是多线程杀手,分分钟让你的服务器在并发时输出 "2023 年 13 月 32 日",堪比时空穿越。
- 想处理时区?Date默认带时区却又不显示,直到你在纽约调试时发现东京用户的时间快了 13 小时,仿佛打开了《信条》的时间逆转之门。
Java 8 之前的日期处理,就像一场没有地图的冒险,而LocalDate/LocalTime的出现,终于给了程序员一张高清导航图。
二、新旧对比:从 "野生程序员" 到 "优雅工程师"
特性 | 传统 Date/SimpleDateFormat | Java 8 新特性 (LocalDate/LocalTime) |
设计理念 | 可变对象,时区隐藏 | 不可变对象,时区显式处理 |
月份表示 | 0-11 的反人类设计 | 1-12 的正常人类逻辑 |
线程安全 | 非线程安全,并发必翻车 | 线程安全,可放心在多线程环境使用 |
功能丰富度 | 格式化靠拼接,计算靠数学公式 | 内置plusDays/minusMonths等语义化方法 |
时区处理 | 全靠自觉,一不小心就成 "国际玩笑" | ZoneId/ZonedDateTime明确时区,妈妈再也不用担心我搞乱时差 |
举个栗子🌰:用传统方式计算 "3 天后的日期":
Date today = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(today);
calendar.add(Calendar.DAY_OF_MONTH, 3);
Date result = calendar.getTime(); // 每次写都要祈祷别搞反年月日
用新特性:
LocalDate today = LocalDate.now();
LocalDate threeDaysLater = today.plusDays(3); // 像说人话一样写代码,爽!
三、实战指南:新特性让日期处理丝滑如德芙
1. 日期格式化:再也不用背 yyyy-MM-dd 的玄学
场景 1:把 "2023-10-01" 转成 "2023 年 10 月 01 日 星期六"
LocalDate date = LocalDate.of(2023, 10, 1);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 E");
String result = date.format(formatter); // 输出:2023年10月01日 星期日
注意:MM是两位月份,M是一位;dd是两位日期,d是一位,强迫症患者的福音。
场景 2:解析 "2023/10/01" 这种非标准格式
String str = "2023/10/01";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
LocalDate date = LocalDate.parse(str, formatter); // 再也不用手动分割字符串啦!
2. 时间计算:告别小学数学题式编程
场景 1:计算 "从今天起 100 天后是星期几"
LocalDate today = LocalDate.now();
LocalDate future = today.plusDays(100);
DayOfWeek dayOfWeek = future.getDayOfWeek(); // 直接获取枚举值,比如MONDAY/TUESDAY
System.out.println("100天后是:" + dayOfWeek); // 输出:WEDNESDAY(假设今天是周日)
场景 2:计算两个日期相差多少天 / 月 / 年
LocalDate birthDate = LocalDate.of(1990, 1, 1);
LocalDate now = LocalDate.now();
Period period = Period.between(birthDate, now);
System.out.println("年龄:" + period.getYears() + "岁" + period.getMonths() + "个月" + period.getDays() + "天");
// 输出:比如33岁9个月15天(根据当前时间变化)
3. 时区处理:让纽约和东京用户和平共处
场景:把北京时间 "2023-10-01 12:00" 转为纽约时间
ZoneId beijingZone = ZoneId.of("Asia/Shanghai");
ZoneId newYorkZone = ZoneId.of("America/New_York");ZonedDateTime beijingTime = ZonedDateTime.of(2023, 10, 1, 12, 0, 0, 0, beijingZone);
ZonedDateTime newYorkTime = beijingTime.withZoneSameInstant(newYorkZone);DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm z");
System.out.println(newYorkTime.format(formatter)); // 输出:2023-09-30 23:00 America/New_York
知识点:withZoneSameInstant是瞬间转换(物理时间不变),withZoneSameLocal是本地时间转换(可能产生夏令时问题)。
四、常见问题解决方案:专治各种不服
问题 1:如何处理可能为 null 的日期?
反模式:if (date != null) date.getYear();( NullPointerException 警告!)正解:用Optional包裹,或者在 API 中明确要求非 null:
public void processDate(LocalDate date) {// 编译器会强制调用者处理null,比传统Date安全10086倍
}
问题 2:夏令时导致时间跳跃怎么办?
比如美国夏令时结束时,时钟回拨 1 小时,会出现重复的时间。解决方案:使用ZoneRules检查时间是否有效:
ZoneId zone = ZoneId.of("America/Chicago");
LocalDateTime ambiguousTime = LocalDateTime.of(2023, 11, 5, 1, 30);
ZoneRules rules = zone.getRules();
if (rules.isValidLocalDateTime(ambiguousTime)) {// 处理有效时间
} else {// 处理重复时间(通常加1小时)
}
问题 3:想存日期到数据库,用什么类型?
推荐:
- 只存日期用LocalDate,对应数据库DATE类型;
- 存日期时间用LocalDateTime,对应TIMESTAMP类型;
- 再也不用和java.sql.Timestamp搞暧昧了!
五、总结:Java 8 日期时间 API,真香!
从被Date虐到怀疑人生,到用LocalDate优雅处理时间,Java 8 的新特性简直是程序员的救星。记住三个核心类:
- LocalDate:专注日期(年 / 月 / 日),不带时间;
- LocalTime:专注时间(时 / 分 / 秒 / 纳秒),不带日期;
- DateTimeFormatter:格式化和解析的瑞士军刀。
下次再有人让你处理 "2020 年 2 月 30 日" 这种反人类需求,记得甩出DateTimeException异常:"对不起,Java 不支持穿越到不存在的日期哦~"
赶紧抛弃古老的Date吧,让代码像时间一样,流淌得优雅而有序~
相关文章:
8.Java 8 日期时间处理:从 Date 的崩溃到 LocalDate 的优雅自救
一、被 Date 逼疯的程序员:那些年踩过的坑 还记得刚学 Java 时被Date支配的恐惧吗? 想获取 "2023 年 10 月 1 日"?new Date(2023, 9, 1)—— 等等,为什么月份是 9?哦对,Java 的月份从 0 开…...
基于Python的全卷积网络(FCN)实现路径损耗预测
以下是一份详细的基于Python的全卷积网络(FCN)实现路径损耗预测的技术文档。本方案包含理论基础、数据生成、模型构建、训练优化及可视化分析,代码实现约6000字。 基于全卷积网络的无线信道路径损耗预测系统 目录 问题背景与需求分析系统架构设计合成数据生成方法全卷积网络…...
【ubuntu】安装NVIDIA Container Toolkit
目录 安装NVIDIA Container Toolkit 安装依赖 添加密钥和仓库 配置中国科技大学(USTC) 镜像 APT 源 更新 APT 包列表 安装 NVIDIA Container Toolkit 验证安装 重启docker 起容器示例命令 【问题】如何在docker中正确使用GPU? 安装…...

Paimon和Hive相集成
Flink版本1.17 Hive版本3.1.3 1、Paimon集成Hive 将paimon-hive-connector.jar复制到auxlib中,下载链接Index of /groups/snapshots/org/apache/https://repository.apache.org/snapshots/org/apache/paimon/ 通过flink进入查看paimon /opt/softwares/flink-1.…...
精益数据分析(74/126):从愿景到落地的精益开发路径——Rally的全流程管理实践
精益数据分析(74/126):从愿景到落地的精益开发路径——Rally的全流程管理实践 在创业的黏性阶段,如何将抽象的愿景转化为可落地的产品功能?如何在快速迭代中保持战略聚焦?今天,我们通过Rally软…...

HarmonyOS 鸿蒙应用开发进阶:深入理解鸿蒙跨设备互通机制
鸿蒙跨设备互通(HarmonyOS Cross-Device Collaboration)是鸿蒙系统分布式能力的重要体现,通过创新的分布式软总线技术,实现了设备间的高效互联与能力共享。本文将系统性地解析鸿蒙跨设备互通的技术架构、实现原理及开发实践。 跨设…...

Vue.js教学第十五章:深入解析Webpack与Vue项目实战
Webpack 与 Vue 项目详解 在现代前端开发中,Webpack 作为最流行的模块打包工具之一,对于 Vue 项目的构建和优化起着至关重要的作用。本文将深入剖析 Webpack 的基本概念、在 Vue 项目中的应用场景,并详细讲解常用的 Webpack loaders 和 plugins 的配置与作用,同时通过实例…...
深入浅出 Python Testcontainers:用容器优雅地编写集成测试
在现代软件开发中,自动化测试已成为敏捷开发与持续集成中的关键环节。单元测试可以快速验证函数或类的行为是否符合预期,而集成测试则确保多个模块协同工作时依然正确。问题是:如何让集成测试可靠、可重复且易于维护? 这时&#…...

Cmake编译gflags过程记录和在QT中测试
由于在QT中使用PaddleOCR2.8存在这样那样的问题,查找貌似是gflags相关问题导致的,因此从头开始按相关参考文章编译一遍gflags源码,测试结果表明Qt5.14.2中使用MSVC2017X64编译器运行的QTgflags项目是正常。 详细编译步骤如下: 1、…...

项目中Warmup耗时高该如何操作处理
1)项目中Warmup耗时高该如何操作处理 2)如何在卸载资源后Untracked和Other的内存都回收 3)总Triangles的值是否包含了通过GPU Instancing画的三角形 4)有没有用Lua来修复虚幻引擎中对C代码进行插桩Hook的方案 这是第432篇UWA技术知…...

制作一款打飞机游戏53:子弹样式
现在,我们有一个小程序可以发射子弹,但这些子弹并不完美,我们稍后会修复它们。 子弹模式与目标 在开始之前,我想修正一下,因为我观察到在其他射击游戏中有一个我想复制的简单行为。我们有静态射击、瞄准射击和快速射击…...
Windows磁盘无法格式化及磁盘管理
简述:D盘使用了虚拟分区,结果导致无法格式化。 一、无法格式化磁盘 因为以前划分C盘的时候,空间划小了,所以在下载一些程序的依赖包之后爆红。当我想要把D盘的空间分给C盘时,发现D盘无法格式化。在网上没有找到合适的…...
每日算法 -【Swift 算法】Z 字形变换(Zigzag Conversion)详解与实现
Swift | Z 字形变换(Zigzag Conversion)详解与实现 🧩 题目描述 给定一个字符串 s 和一个行数 numRows,请按照从上往下、再从下往上的“Z”字形排列这个字符串,并按行输出最终结果。例如: 输入ÿ…...

Docker运维-5.3 配置私有仓库(Harbor)
1. harbor的介绍 Harbor(港湾),是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器。以前的镜像私有仓库采用官方的 Docker Registry,不便于管理镜像。 Harbor 是由 VMWare 在 Docker Registry 的基础之上进行了二次封装,加进去了很…...

day 36
利用前面所学知识,对之前的信贷项目,利用神经网络训练 # 先运行之前预处理好的代码 import pandas as pd import pandas as pd #用于数据处理和分析,可处理表格数据。 import numpy as np #用于数值计算,提供了高效的数组…...

mybatis-plus使用记录
MyBatis-Plus 学习笔记 一、 快速入门 MyBatis-Plus (MP) 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 1. 引入 Maven 依赖 要使用 MyBatis-Plus,首先需要在项目的 pom.xml 文件中引入相…...

Mcu_Bsdiff_Upgrade
系统架构 概述 MCU BSDiff 升级系统通过使用二进制差分技术,提供了一种在资源受限的微控制器上进行高效固件更新的机制。系统不传输和存储完整的固件映像,而是只处理固件版本之间的差异,从而显著缩小更新包并降低带宽要求。 该架构遵循一个…...

有监督学习——决策树
任务 1、基于iris_data.csv数据,建立决策树模型,评估模型表现; 2、可视化决策树结构; 3、修改min_samples_leaf参数,对比模型结果 代码工具:jupyter notebook 参考资料 20.23 决策树(1)_哔哩哔哩_bil…...

华为OD机试真题——启动多任务排序(2025B卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
2025 B卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…...
AWS云与第三方通信最佳实践:安全、高效的数据交互方案
引言 在当今的云计算时代,企业经常需要在AWS云环境中存储和处理数据,同时还需要与第三方应用或服务进行数据交互。如何安全、高效地实现这种通信是许多企业面临的挑战。本文将详细探讨几种AWS云与第三方通信的方案,并分析它们的优缺点,帮助您为自己的业务场景选择最佳解决…...
Ubuntu Server 24 设置 WiFi 网络的方案
一、配置流程 1. 确认无线网卡信息 首先需明确无线网卡接口名称及当前连接状态: ip link show # 查看网络接口(寻找状态为 "UP" 的无线接口,如 wlan0、wlx* 或 wlp1s0) iwconfig # 确认无线网…...
【redis】redis和hiredis的基本使用
总结: 介绍了一下redis和hiredis的安装步骤,用一个简单的demo演示了使用redis的基本过程。 启动redis步骤 1、下载redis:https://github.com/redis/redis 2、编译命令:make 3、编译产物:libredis.a(静…...

大模型时代,Python 近红外光谱与 Transformer 模型:学习的必要性探究
在当下大语言模型盛行的时代,各类新技术如潮水般不断涌现,让人应接不暇。身处这样的浪潮之中,不少人心中都会泛起疑问:Python 近红外光谱和 Transformer 模型还有学习的必要性吗?今天,就让我们深入探讨一番…...
产品经理常用术语大全
作为一名产品经理,不仅需要具备跨领域的知识和技能,还需要熟练掌握一系列专业术语,以便更有效地沟通、规划和执行产品开发过程中的各项任务。以下是一篇详细介绍产品经理日常工作中常见术语的文章,旨在帮助新手快速入门࿰…...

梯度优化提示词:精准引导AI分类
基于梯度优化的提示词工程方法,通过迭代调整提示词的嵌入向量,使其能够更有效地引导模型做出正确分类。 数据形式 训练数据 train_data 是一个列表,每个元素是一个字典,包含两个键: text: 需要分类的文本描述label: 对应的标签(“冲动"或"理性”)示例数据: …...

AUTOSAR 运行时环境 (RTE)
目录 往期推荐 什么是运行时环境? AUTOSAR 中的运行时环境 (RTE) RTE 的应用 RTE 的生成 关于RTE API的一些信息 RTE生成后文件之间的关系 往期推荐 2025汽车行业新宠:欧企都在用的工具软件ETAS工具链自动化实战指南<一>ET…...
Bolt.new:重塑 Web 开发格局的 AI 利器
根据 Menlo Ventures 2024 年的调查,在主流 AI 应用场景中,AI 编程工具的采用率以 51% 位居榜首,代码生成成为最易落地且受欢迎的场景。科技巨头谷歌 CEO Sundar Pichai 在 2024 年 10 月财报会议上透露,公司超四分之一的新代码由…...
RK3588 RKNN ResNet50推理测试
RK3588 RKNN ResNet50推理测试 一、背景二、性能数据三、操作步骤3.1 安装依赖3.2 安装rknn-toolkit,更新librknnrt.so3.3 下载推理图片3.4 生成`onnx`模型转换脚本3.5 生成rknn模型3.6 运行rknn模型一、背景 在嵌入式设备上进行AI推理时,我们面临着算力有限、功耗敏感等挑战…...

SQLMesh 宏操作符详解:提升 SQL 查询的灵活性与效率
SQLMesh 提供了一系列强大的宏操作符(如 WITH、JOIN、WHERE 等),用于动态构建 SQL 查询。这些操作符不仅简化了复杂查询的编写,还提高了代码的可读性和可维护性。本文将深入探讨这些操作符的使用场景、语法及实际案例,…...
leetcode513.找树左下角的值:递归深度优先搜索中的最左节点追踪之道
一、题目本质与核心诉求解析 在二叉树算法问题中,"找树左下角的值"是一个典型的结合深度与位置判断的问题。题目要求我们找到二叉树中最深层最左边的节点值,这里的"左下角"有两个关键限定: 深度优先:必须是…...