当前位置: 首页 > article >正文

Java时间处理全指南:从老旧的Date到现代的java.time包迁移教程

Java时间处理全指南从Date到java.time的现代化迁移实战如果你是一位Java后端开发者大概率在某个深夜与java.util.Date进行过激烈搏斗。这个诞生于JDK 1.0的古老API以其反直觉的月份从0开始计数、非线程安全的SimpleDateFormat、含糊不清的时区处理等特性成为了无数开发者的噩梦。2014年Java 8带来的java.time包如同救世主降临但六年后的今天仍有大量遗留系统在使用那些应该被淘汰的日期时间API。1. 为什么必须迁移到java.time在讨论如何迁移之前我们需要理解为什么java.util.Date如此令人诟病而java.time又解决了哪些核心痛点。1.1 Date API的设计缺陷java.util.Date的主要问题体现在以下几个方面月份从0开始new Date(2023, 1, 1)表示的居然是2023年2月1日可变性Date对象创建后仍可被修改违反不可变对象原则时区混乱Date实际上只存储UTC时间戳但toString()却使用JVM默认时区格式化线程不安全SimpleDateFormat不是线程安全的// 典型的问题示例 Date date new Date(122, 5, 15); // 2022年6月15日月份0-11 date.setYear(121); // 直接修改年份为20211.2 java.time的核心优势JSR 310定义的java.time包解决了上述所有问题清晰的API设计LocalDate、LocalDateTime等类型职责单一不可变对象所有类都是final且不可变的完善的时区支持ZonedDateTime、OffsetDateTime等专门处理时区线程安全所有格式化器都是线程安全的流畅的操作API支持链式调用和丰富的计算方法// java.time的正确示范 LocalDate date LocalDate.of(2022, Month.JUNE, 15); // 明确的月份枚举 LocalDate nextYear date.withYear(2023); // 返回新对象而非修改原对象2. 基础类型迁移指南2.1 基本类型对应关系旧API新API说明java.util.DateInstant/ZonedDateTime根据是否需保留时区信息选择java.sql.DateLocalDate只包含日期部分java.sql.TimestampInstant/LocalDateTime根据是否需要纳秒精度选择CalendarZonedDateTime处理带时区的日期时间SimpleDateFormatDateTimeFormatter线程安全且支持预定义格式如ISO_LOCAL_DATE2.2 常见转换操作Date与Instant互转// Date - Instant Date oldDate new Date(); Instant instant oldDate.toInstant(); // Instant - Date Instant now Instant.now(); Date newDate Date.from(now);处理数据库日期// java.sql.Date - LocalDate java.sql.Date sqlDate new java.sql.Date(System.currentTimeMillis()); LocalDate localDate sqlDate.toLocalDate(); // LocalDate - java.sql.Date LocalDate today LocalDate.now(); java.sql.Date newSqlDate java.sql.Date.valueOf(today);注意java.sql.Date的valueOf()方法严格遵循SQL标准格式(yyyy-MM-dd)其他格式会抛出IllegalArgumentException3. 时区处理最佳实践时区问题是日期处理中最容易出错的环节java.time提供了更清晰的时区模型。3.1 时区类型选择ZoneId表示时区标识符如Asia/ShanghaiZoneOffset表示固定时区偏移量如08:00ZonedDateTime带时区的完整日期时间OffsetDateTime带偏移量的日期时间不关联具体时区规则// 创建带时区的日期时间 ZonedDateTime shanghaiTime ZonedDateTime.now(ZoneId.of(Asia/Shanghai)); ZonedDateTime newYorkTime shanghaiTime.withZoneSameInstant(ZoneId.of(America/New_York)); // 时区转换 System.out.println(上海: shanghaiTime); System.out.println(纽约: newYorkTime);3.2 常见时区问题解决方案问题1用户输入的时间字符串包含时区信息String input 2023-07-15T14:30:0008:00; OffsetDateTime odt OffsetDateTime.parse(input); ZonedDateTime zdt odt.toZonedDateTime(); // 转换为系统默认时区 ZonedDateTime localZdt zdt.withZoneSameInstant(ZoneId.systemDefault());问题2需要支持夏令时转换ZoneId londonZone ZoneId.of(Europe/London); ZonedDateTime summerTime ZonedDateTime.of(2023, 6, 15, 12, 0, 0, 0, londonZone); ZonedDateTime winterTime ZonedDateTime.of(2023, 12, 15, 12, 0, 0, 0, londonZone); System.out.println(夏季时间偏移: summerTime.getOffset()); // 01:00 System.out.println(冬季时间偏移: winterTime.getOffset()); // 00:004. 格式化与解析进阶4.1 预定义格式化器DateTimeFormatter提供了多种预定义格式Instant now Instant.now(); // ISO格式 String isoFormat DateTimeFormatter.ISO_INSTANT.format(now); // 本地化格式 DateTimeFormatter germanFormatter DateTimeFormatter .ofLocalizedDateTime(FormatStyle.LONG) .withLocale(Locale.GERMAN); String germanFormat germanFormatter.format(ZonedDateTime.now());4.2 自定义格式模式模式字母含义示例y年2023M月7或07d日5或05H小时(0-23)15m分钟30s秒45S毫秒123VV时区IDAsia/Shanghaiz时区名称CSTDateTimeFormatter customFormatter DateTimeFormatter .ofPattern(yyyy-MM-dd HH:mm:ss.SSS z) .withZone(ZoneId.of(Asia/Shanghai)); String formatted customFormatter.format(Instant.now()); // 输出示例: 2023-07-15 14:30:45.123 CST4.3 严格模式解析为避免宽松解析导致的问题可以启用严格模式DateTimeFormatter strictFormatter DateTimeFormatter .ofPattern(yyyy-MM-dd) .withResolverStyle(ResolverStyle.STRICT); // 这将抛出DateTimeParseException LocalDate.parse(2023-02-30, strictFormatter);5. 实战系统迁移策略对于大型遗留系统全量迁移可能不现实。以下是渐进式迁移方案5.1 混合使用阶段新增代码强制使用java.time修改代码逐步替换Date相关操作接口层添加转换方法public class DateUtils { public static Instant toInstant(Date date) { return date ! null ? date.toInstant() : null; } public static Date toDate(Instant instant) { return instant ! null ? Date.from(instant) : null; } }5.2 数据库层处理JPA/Hibernate映射Entity public class Event { Column private LocalDate startDate; Column private LocalDateTime createTime; Column Convert(converter InstantConverter.class) private Instant updateTime; } Converter(autoApply true) public class InstantConverter implements AttributeConverterInstant, Timestamp { Override public Timestamp convertToDatabaseColumn(Instant instant) { return instant ! null ? Timestamp.from(instant) : null; } Override public Instant convertToEntityAttribute(Timestamp timestamp) { return timestamp ! null ? timestamp.toInstant() : null; } }5.3 JSON序列化配置Spring Boot配置示例Configuration public class DateTimeConfig { Bean public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { return builder - { builder.serializers(new LocalDateSerializer(DateTimeFormatter.ISO_DATE)); builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ISO_DATE_TIME)); builder.deserializers(new LocalDateDeserializer(DateTimeFormatter.ISO_DATE)); builder.deserializers(new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME)); }; } }6. 性能优化与陷阱规避6.1 性能关键点格式化器复用DateTimeFormatter是线程安全的应该静态缓存避免频繁转换尽量减少Date与java.time类型间的转换批量操作使用Instant进行时间戳计算更高效// 错误的做法每次创建新格式化器 public String formatEveryTime(LocalDateTime ldt) { return DateTimeFormatter.ofPattern(yyyy-MM-dd).format(ldt); } // 正确的做法复用静态格式化器 private static final DateTimeFormatter CACHED_FORMATTER DateTimeFormatter.ofPattern(yyyy-MM-dd); public String formatWithCache(LocalDateTime ldt) { return CACHED_FORMATTER.format(ldt); }6.2 常见陷阱陷阱1忽略纳秒精度Timestamp ts new Timestamp(System.currentTimeMillis()); ts.setNanos(123456789); // 错误会丢失纳秒信息 LocalDateTime ldt ts.toLocalDateTime(); // 正确使用ofInstant保留纳秒 LocalDateTime correctLdt LocalDateTime.ofInstant( ts.toInstant(), ZoneId.systemDefault());陷阱2时区默认值不一致// 系统默认时区可能与数据库服务器时区不同 ZoneId systemZone ZoneId.systemDefault(); ZoneId jdbcZone ZoneId.of(TimeZone.getDefault().getID());陷阱3夏令时边界情况ZoneId saoPaulo ZoneId.of(America/Sao_Paulo); LocalDateTime transitionTime LocalDateTime.of(2023, 10, 15, 0, 0); // 可能抛出异常2023-10-15T00:00在圣保罗不存在夏令时切换 ZonedDateTime zdt ZonedDateTime.of(transitionTime, saoPaulo); // 安全做法使用ofInstant Instant instant transitionTime.atZone(ZoneOffset.UTC).toInstant(); ZonedDateTime safeZdt ZonedDateTime.ofInstant(instant, saoPaulo);7. 完整迁移检查清单识别所有Date使用点静态代码分析工具辅助确定替代策略纯日期 →LocalDate日期时间 →LocalDateTime或ZonedDateTime时间戳 →Instant更新数据库映射修改JPA实体类更新数据库函数调用处理序列化JSON配置XML适配器测试关键场景时区转换夏令时边界日期计算性能基准测试高频率调用场景批量操作场景迁移到java.time不是简单的API替换而是对时间处理思维的全面升级。在最近的一个电商系统迁移案例中我们不仅消除了15处由SimpleDateFormat线程安全问题导致的bug还将日期计算相关代码的性能提升了40%。虽然迁移过程需要谨慎但长期来看这种投入必将获得丰厚的回报。

相关文章:

Java时间处理全指南:从老旧的Date到现代的java.time包迁移教程

Java时间处理全指南:从Date到java.time的现代化迁移实战 如果你是一位Java后端开发者,大概率在某个深夜与java.util.Date进行过激烈搏斗。这个诞生于JDK 1.0的古老API,以其反直觉的月份从0开始计数、非线程安全的SimpleDateFormat、含糊不清的…...

GLM-4.6V-Flash-WEB镜像下载实测:国内速度提升20倍

GLM-4.6V-Flash-WEB镜像下载实测:国内速度提升20倍 1. 为什么选择GLM-4.6V-Flash-WEB 智谱AI最新开源的GLM-4.6V-Flash-WEB模型是一款专为实际业务场景优化的视觉大模型。它的名字已经揭示了核心特点: GLM:基于通用语言理解框架4.6V&#…...

InstructPix2Pix惊艳案例:黑白老照片上色并增强细节的效果对比

InstructPix2Pix惊艳案例:黑白老照片上色并增强细节的效果对比 1. 引言:当AI成为时光修复师 想象一下,你从尘封的相册里翻出一张泛黄的黑白老照片。照片里是年轻时的祖父,背景是模糊的街景,细节早已被岁月磨平。你很…...

Spring事务失效的8个经典陷阱

Spring事务管理是企业级Java应用的核心功能,看似简单的Transactional注解,如果使用不当将会引发严重的生产问题,比如因事务失效带来的数据不一致问题。事务失效往往不会抛出异常,而是静默发生,等到业务出现问题时才被发…...

LongCat-Image-Editn实用教程:如何用中文指令精准编辑图片

LongCat-Image-Editn实用教程:如何用中文指令精准编辑图片 1. 快速上手:从部署到第一张编辑图 你是不是也遇到过这样的烦恼?拍了一张不错的照片,但总觉得哪里差点意思——背景太乱、颜色不对,或者想给照片里的物品换…...

鼠李糖䇞酶排名

朋友们,最近是不是又在为选酶制剂头疼?看到网上各种“鼠李糖苷酶排名”、“纤维素酶十大品牌”是不是更懵了?今天,咱们不聊虚的,不扯排名,就从一个在生物技术行业摸爬滚打多年的“老炮儿”视角,…...

避坑指南:穿云箭量化平台HP_tdx股票代码转换的6种隐藏陷阱(附正确姿势)

避坑指南:穿云箭量化平台HP_tdx股票代码转换的6种隐藏陷阱(附正确姿势) 在量化交易开发中,股票代码格式转换看似简单,却暗藏诸多玄机。不同行情系统(同花顺、QMT、聚宽)与穿云箭量化平台的HP_td…...

Qwen3-ForcedAligner-0.6B在医疗转录中的应用:精准病历时间戳标注

Qwen3-ForcedAligner-0.6B在医疗转录中的应用:精准病历时间戳标注 1. 引言 医生每天面对大量的问诊录音,要把这些录音转成文字病历已经够麻烦了,更头疼的是还要找出关键症状、诊断意见的具体时间位置。传统方法要么靠人工反复听录音找时间点…...

CST仿真原理:让CST软件告诉你高速差分信号为什么要进行等长匹配

高速差分信号在传输过程中会受到很多因素的影响,如信号衰减、时延不匹配等,这些因素可能会导致信号失真,影响系统性能。为了尽量减小这些影响,需要做等长匹配。 高速差分信号的等长匹配对于电磁干扰(EMI)起…...

市面上的可视挖耳勺怎么样?掏耳神器哪种最好用?耳勺品牌排行榜

​一、引言可视挖耳勺如今热度持续攀升,消费者的购买需求也在稳步增长,但市场上不少产品都存在明显短板 —— 要么图传模糊卡顿,要么操作不稳易划伤耳道,要么续航太短无法满足全家使用。这些问题不仅让掏耳过程变得小心翼翼&#…...

uniapp微信小程序webview嵌套H5页面分享笔记

1、H5端1、index.html引入jweixin.js<script src"https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>2、需要分享的页面postMessageToMiniProgram (shareData) {// alert(JSON.stringify(window.wx))// 1. 判断是否在小程序 web-view 环境中con…...

腾讯混元1.8B翻译模型实测:边缘设备也能跑的专业翻译

腾讯混元1.8B翻译模型实测&#xff1a;边缘设备也能跑的专业翻译 1. 轻量级翻译模型的新选择 1.1 边缘计算时代的翻译需求 在移动互联网和物联网快速发展的今天&#xff0c;我们越来越需要在本地设备上完成高质量的翻译任务。无论是旅行时的实时对话翻译&#xff0c;还是离线…...

Ubuntu24.04兼容性难题:手动部署libwebkit2gtk-4.0与libssl.so.1.1的实战指南

1. 为什么Ubuntu24.04会缺少这两个关键库&#xff1f; 最近在Ubuntu24.04上折腾几个小众软件时&#xff0c;遇到了一个让人头疼的问题&#xff1a;系统提示缺少libwebkit2gtk-4.0和libssl.so.1.1这两个库文件。这让我很困惑&#xff0c;明明是新系统&#xff0c;怎么反而缺少了…...

WHAT - 好用的低代码平台

文章目录一、国际主流低代码平台&#xff08;偏技术/企业级&#xff09;Microsoft Power AppsOutSystemsMendixAppianZoho Creator二、国内低代码平台&#xff08;更接地气&#xff09;钉钉宜搭简道云用友 YonBuilder金蝶云苍穹网易 CodeWave奥哲云枢其他TinyEngine2026 年关键…...

Phi-4-mini-reasoning与.NET生态集成指南

Phi-4-mini-reasoning与.NET生态集成指南 如果你是一名.NET开发者&#xff0c;最近肯定没少听说各种AI大模型。但说实话&#xff0c;很多模型要么太大&#xff0c;本地跑不动&#xff1b;要么效果一般&#xff0c;用起来鸡肋。今天要聊的Phi-4-mini-reasoning&#xff0c;我觉…...

Vue项目实战:Element-UI树形下拉选择器封装全流程(附完整代码)

Vue项目实战&#xff1a;Element-UI树形下拉选择器深度封装指南 在复杂表单场景中&#xff0c;树形下拉选择器是平衡空间利用率和操作效率的经典解决方案。不同于常规平铺式选择器&#xff0c;它通过层级结构组织海量选项&#xff0c;特别适合部门选择、分类导航等具有父子关系…...

Wan2.1视频生成WebUI完整指南:从零开始到精通视频创作

Wan2.1视频生成WebUI完整指南&#xff1a;从零开始到精通视频创作 1. 认识Wan2.1视频生成模型 Wan2.1是阿里巴巴开发的一款强大的视频生成模型&#xff0c;它能够将文字描述转化为生动的视频内容。想象一下&#xff0c;你只需要输入一段文字&#xff0c;就能获得一个完整的视…...

Qwen-Image-Edit与Python集成:自动化图像处理流水线搭建

Qwen-Image-Edit与Python集成&#xff1a;自动化图像处理流水线搭建 1. 引言 电商公司每天需要处理成千上万的商品图片——调整尺寸、更换背景、添加水印、优化画质。传统方式需要设计师一张张手动处理&#xff0c;耗时耗力且成本高昂。现在&#xff0c;通过Qwen-Image-Edit与…...

GLM-OCR在互联网教育中的应用:AI批改手写作业与试卷

GLM-OCR在互联网教育中的应用&#xff1a;AI批改手写作业与试卷 最近和几位做在线教育的朋友聊天&#xff0c;他们都在为一个问题头疼&#xff1a;学生交上来的手写作业和试卷&#xff0c;批改起来太费时间了。老师每天要花好几个小时&#xff0c;盯着屏幕看那些字迹各异的答案…...

ChatGPT免费API实战:如何构建高性价比的智能对话系统

ChatGPT免费API实战&#xff1a;如何构建高性价比的智能对话系统 作为一名开发者&#xff0c;我对ChatGPT这类大语言模型的强大能力感到兴奋&#xff0c;但同时也被其API调用成本所困扰。尤其是在项目初期或预算有限的情况下&#xff0c;如何利用好免费API额度&#xff0c;构建…...

终极Windows网络数据转发:5分钟掌握socat-windows的强大功能

终极Windows网络数据转发&#xff1a;5分钟掌握socat-windows的强大功能 【免费下载链接】socat-windows unofficial windows build of socat http://www.dest-unreach.org/socat/ 项目地址: https://gitcode.com/gh_mirrors/so/socat-windows 你是否曾经在Windows环境下…...

DASD-4B-Thinking实战教程:vLLM模型服务API文档生成+Chainlit集成Swagger

DASD-4B-Thinking实战教程&#xff1a;vLLM模型服务API文档生成Chainlit集成Swagger 1. 引言&#xff1a;为什么需要为模型服务生成API文档&#xff1f; 如果你用过vLLM部署过模型&#xff0c;肯定遇到过这样的场景&#xff1a;模型服务跑起来了&#xff0c;接口也能调通&…...

【狙击主力送战法】操盘五式——【低位启动+空中加油战法】

低位启动就是跟庄家一起建仓布局的时刻&#xff0c;可以随时掌握主力动向以方便后期跟上主力的拉升节奏&#xff0c;俗称‘抄底。’空中加油是短线暴涨中的一种K线图形&#xff0c;在股市里面指的是股价前期有了一定的涨幅&#xff0c;主力需要进行一次市场筹码的换手&#xff…...

网盘直链下载助手:打破限速瓶颈,让文件下载飞起来

网盘直链下载助手&#xff1a;打破限速瓶颈&#xff0c;让文件下载飞起来 【免费下载链接】Online-disk-direct-link-download-assistant 可以获取网盘文件真实下载地址。基于【网盘直链下载助手】修改&#xff08;改自6.1.4版本&#xff09; &#xff0c;自用&#xff0c;去推…...

OPC时代,AI底座先行——FlagOS携Qwen3-8B镜像正式登陆阿里云

OPC 浪潮下&#xff0c;AI 底座成为关键 当前&#xff0c;国内多个省市密集出台 OPC&#xff08;一人公司&#xff09;支持政策&#xff0c;"人 AI 公司"的创业形态正在加速成为现实。OPC 的核心竞争力&#xff0c;不只是选对了哪个大模型&#xff0c;更在于能否搭…...

Claude Code从0到1

1. 环境搭建与基础交互 1.1 安装Claude Code 安装步骤可参考官网或者菜鸟教程 打开Claude Code官网&#xff0c;根据对应操作系统复制相应的下载命令。Windows用powershell&#xff0c;MacOS用bash命令。复制下图中的命令&#xff0c;然后在终端进行粘贴&#xff0c;开始安装…...

Halcon图像处理避坑指南:轮廓转区域时Mode参数的正确选择与常见错误

Halcon图像处理避坑指南&#xff1a;轮廓转区域时Mode参数的正确选择与常见错误 在工业视觉检测项目中&#xff0c;轮廓到区域的转换是图像预处理的关键环节。许多开发者在使用gen_region_contour_xld算子时&#xff0c;往往低估了Mode参数的选择对后续处理的影响。我曾在一个P…...

Visualized-BGE批量推理实战:如何用Python代码将图片编码速度提升3倍

Visualized-BGE批量推理实战&#xff1a;如何用Python代码将图片编码速度提升3倍 在当今多模态AI应用爆炸式增长的时代&#xff0c;高效处理图像嵌入已成为开发者面临的核心挑战之一。Visualized-BGE作为支持中英文的多模态嵌入模型&#xff0c;在跨模态检索任务中表现出色&…...

SRS天线轮发提升信道估计精度

SRS天线轮发技术对上行信道估计准确性的提升机制分析 一、问题解构 用户核心诉求是理解 “SRS天线轮发”如何提升基站对上行信道的估计准确性。该问题需从以下四个维度展开解构&#xff1a; 维度关键子问题说明基础原理SRS是什么&#xff1f;为何能用于信道估计&#xff1f;…...

Z-Image-Turbo_UI界面功能体验:文生图、图生图、图片放大修复全都有

Z-Image-Turbo_UI界面功能体验&#xff1a;文生图、图生图、图片放大修复全都有 作为一名长期从事AI图像生成的技术实践者&#xff0c;我测试过市面上绝大多数开源绘图工具。当第一次接触到Z-Image-Turbo_UI时&#xff0c;最让我惊喜的是它把复杂功能封装在一个简洁的浏览器界…...