Java嚴格模式withResolverStyle解析日期錯誤及解決方案

在Java中使用DateTimeFormatter并啟用嚴格模式(ResolverStyle.STRICT)時,解析日期字符串"2025-06-01"報錯的根本原因是:模式字符串中的年份格式yyyy被解釋為YearOfEra(紀元年份),而非Year(公歷年份)。在嚴格模式下,解析器要求所有字段必須完整且一致,而LocalDate需要Year字段(而非YearOfEra)來構建對象,導致轉換失敗。

解決方案:使用uuuu代替yyyy

將模式中的年份占位符從yyyy改為uuuu,明確指定使用公歷年份(Year字段):

java

復制

下載

private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd").withResolverStyle(ResolverStyle.STRICT); // 嚴格模式

原因詳解

  1. 字段差異

    • yyyy?→ 解析為?YearOfEra(紀元年份),例如?2025?表示“公元2025年”。

    • uuuu?→ 解析為?Year(公歷年份),直接對應ISO年份體系。

  2. 嚴格模式的要求

    • ResolverStyle.STRICT下,解析器不會自動補全缺失字段(如紀元信息)。

    • 錯誤信息中的TemporalAccessor包含:

      plaintext

      復制

      下載

      {DayOfMonth=1, MonthOfYear=6, YearOfEra=2025}, ISO

      缺少Year字段,只有YearOfEra,無法直接構建LocalDate

  3. uuuu的優勢

    • 直接生成Year字段,與LocalDate所需字段一致。

    • 避免紀元歧義,尤其處理公元前/后的日期更安全。

驗證修復后的代碼

java

復制

下載

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;public class StrictDateParsing {private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd").withResolverStyle(ResolverStyle.STRICT); // 使用 uuuupublic static void main(String[] args) {String dateStr = "2025-06-01";LocalDate date = LocalDate.parse(dateStr, DATE_FORMATTER); // 解析成功System.out.println(date); // 輸出: 2025-06-01}
}

關鍵結論

占位符含義嚴格模式下的行為
yyyy紀元年份解析為YearOfEra,導致構建失敗
uuuu公歷年份解析為Year,與LocalDate兼容

最佳實踐
在嚴格模式中始終使用uuuu表示年份,確保日期字段與LocalDate的要求完全匹配,避免解析錯誤。

package com.weiyu.utils;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.util.ArrayList;
import java.util.List;public class DateUtils {// 標準模式// private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("uuuu-MM-dd")// 啟用嚴格模式,使用 ResolverStyle.STRICT 嚴格模式,拒絕無效日期(如 2023-02-29),自動處理閏年、月份天數等復雜邏輯// 啟用嚴格模式,ofPattern必設置為"uuuu-MM-dd").withResolverStyle(ResolverStyle.STRICT);/*** 有效檢查* @param dateStr 字符串* @return 提示信息*/public static String isValidDate(String dateStr) {// 1. 空值檢查if (dateStr == null) return "日期字符串不能為null";// 2. 空白檢查if (dateStr.isEmpty()) {return "日期字符串不能為空";}return "";}/*** 轉換為 LocalDate 格式的日期* @param dateStr 字符串* @return LocalDate 格式的日期*/public static LocalDate parseDate(String dateStr) {// 檢查日期字符串格式String msg = isValidDate(dateStr);if (!msg.isEmpty()) {throw new RuntimeException(msg);}try {// 解析日期return LocalDate.parse(dateStr, DATE_FORMATTER);} catch (DateTimeParseException e) {// 格式錯誤處理throw new IllegalArgumentException("日期格式錯誤,應為 yyyy-MM-dd,并且為有效日期", e);}}/*** 轉換為開始時間(當天的開始時刻 00:00:00)* @param dateStr 字符串* @return LocalDateTime 格式的日期時間*/public static LocalDateTime parseBeginDateTime(String dateStr) {return parseDate(dateStr).atStartOfDay();}/*** 轉換為結束時間(當天的最后一刻 23:59:59.999999999)* @param dateStr 字符串* @return LocalDateTime 格式的日期時間*/public static LocalDateTime parseEndDateTime(String dateStr) {return parseDate(dateStr).atTime(LocalTime.MAX);}/*** 將字符數組轉換為日期數組,如:["2025-06-01", "2026-06-10"] 轉換為 [beginDate, endDate]* @param dateStrList 字符數組* @return 日期數組,只限開始日期和結束日期,[beginDate, endDate]*/public static List<LocalDate> parseDateRange(List<String> dateStrList) {List<LocalDate> dateList = new ArrayList<>();if (dateStrList == null || dateStrList.size() != 2) {dateList.add(LocalDate.now());dateList.add(LocalDate.now());} else {try {dateList.add(parseDate(dateStrList.get(0)));dateList.add(parseDate(dateStrList.get(1)));} catch (DateTimeParseException e) {dateList.add(LocalDate.now());dateList.add(LocalDate.now());}}// 檢查日期邏輯關系,開始時間大于結束時間if (dateList.get(0).isAfter(dateList.get(1))) {LocalDate maxDate = dateList.get(0);dateList.set(0, dateList.get(1));dateList.set(1,maxDate);}return dateList;}/*** 將字符數組轉換為日期數組,如:["2025-06-01", "2026-06-10"] 轉換為 [beginDateTime, endDateTime]* @param dateStrList 字符數組* @return 時間數組,只限開始時間和結束時間,[beginDateTime, endDateTime]*/public static List<LocalDateTime> parseDateTimeRange(List<String> dateStrList) {List<LocalDate> dateList = parseDateRange(dateStrList);List<LocalDateTime> dateTimeList = new ArrayList<>();dateTimeList.add(dateList.get(0).atStartOfDay());dateTimeList.add(dateList.get(1).atTime(LocalTime.MAX));return dateTimeList;}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/908705.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/908705.shtml
英文地址,請注明出處:http://en.pswp.cn/news/908705.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java中的泛型底層是怎樣的

Java 泛型深入底層原理解析&#xff1a;類型擦除與橋方法的真相 一、Java中的偽泛型 Java 從 JDK 1.5 引入泛型之后&#xff0c;大大提升了代碼的類型安全性與可讀性。但泛型的底層實現并不像 C 的模板機制那樣是“真正的泛型”&#xff0c;Java 的泛型是偽泛型&#xff0c;在…

Spring Boot 從Socket 到Netty網絡編程(上):SOCKET 基本開發(BIO)與改進(NIO)

前言 無論是軟件還是硬件的本質都是要解決IO問題&#xff08;輸入、輸出&#xff09;&#xff0c;再說回網絡編程本質上都是基于TCP/UP的開發&#xff0c;socket是在此基礎上做的擴展與封裝&#xff0c;而Netty又是對socket做的封裝。本文旨在通過相關案例對socket進行探討。 一…

【大模型LLM學習】function call/agent學習記錄

【大模型LLM學習】function call/agent學習記錄 0 前言1 langchain實現function call2 調用本地模型3 微調本地模型3.1 few-shot調用Claude生成Q-A對3.2 tools格式3.3 agent微調格式3.4 swift微調 p.s. 0 前言 記錄一下使用langchain做簡單的function call/agent(或者說意圖識別…

【碎碎念】寶可夢 Mesh GO : 基于MESH網絡的口袋妖怪 寶可夢GO游戲自組網系統

目錄 游戲說明《寶可夢 Mesh GO》 —— 局域寶可夢探索Pokmon GO 類游戲核心理念應用場景Mesh 特性 寶可夢玩法融合設計游戲構想要素1. 地圖探索&#xff08;基于物理空間 廣播范圍&#xff09;2. 野生寶可夢生成與廣播3. 對戰系統4. 道具與通信5. 延伸玩法 安全性設計 技術選…

Puppeteer測試框架 - Node.js

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】

compose 組件 ---無ui組件

在 Jetpack Compose 中&#xff0c;確實存在不直接參與 UI 渲染的組件&#xff0c;它們主要用于邏輯處理、狀態管理或副作用控制。這些組件雖然沒有視覺界面&#xff0c;但在架構中扮演重要角色。以下是常見的非 UI 組件及其用途&#xff1a; 1. 無 UI 的 Compose 組件分類 (…

圖像超分辨率

圖像超分辨率 用AI當“像素偵探”&#xff0c;從模糊中重建合理高清細節&#xff0c;讓看不見的細節“無中生有”。 舉個生活例子 假設你有一張模糊的老照片&#xff0c;通過超分辨率技術&#xff0c;它能變成清晰的高清照片&#xff1a; 低分辨率圖像超分辨率結果 傳統放…

多線程語音識別工具

軟件介紹 本文介紹一款支持大廠接口的語音轉文字工具&#xff0c;具備免配置、免費使用的特點。 軟件特性 該工具是一款完全免費的桌面端應用程序&#xff0c;部署于開源社區平臺&#xff0c;其核心優勢在于整合了多家技術供應商的接口資源。 操作方式 用戶只需將音頻…

金融預測模型開發:數據預處理、機器學習預測與交易策略優化

金融預測模型開發:數據預處理、機器學習預測與交易策略優化 概述 本文將詳細介紹一個完整的金融預測模型開發流程,包含數據預處理、機器學習預測和交易策略優化三個核心模塊。我們使用Python實現一個端到端的解決方案,適用于股票價格預測和量化交易策略開發。 # 導入必要…

triton學習筆記7: GEMM相關

這是之前的學習筆記 triton puzzles part1triton puzzles part2triton puzzles part3triton tutorials part1triton tutorials: part2triton tutorails: part3 這是triton tutorials里最后一篇關于GEMM的系列了 GEMM的知識可以參考這篇&#xff0c;寫的非常詳細具體https://…

食養有方:進行性核上性麻痹患者的健康飲食指南

進行性核上性麻痹是一種罕見的神經系統變性疾病&#xff0c;患者常出現吞咽困難、肢體運動障礙等癥狀&#xff0c;合理的飲食安排不僅能保證營養供給&#xff0c;還能緩解不適&#xff0c;提高生活質量。以下是適合這類患者的健康飲食建議。 ?患者飲食應遵循 “均衡、細軟、易…

使用ORM Bee (ormbee) ,如何利用SQLAlchemy的模型生成數據庫表.

使用ORM Bee (ormbee) &#xff0c;如何利用SQLAlchemy的模型生成數據庫表. 將原來SQLAlchemy的模型&#xff0c;修改依賴為&#xff1a; from bee.helper import SQLAlchemy 然后就可以開始生成了。很簡單&#xff0c;主要是兩個接口。 db.create_all(True) #創建所有模型的表…

C# 使用正則表達式

C# 使用正則表達式 /// <summary> /// 測試正則表達式 /// </summary> private static void test022() {//檢查是否匹配&#xff1a;Regex.IsMatch(currencyValue, pattern); 或 new Regex(...).IsMatch(currencyValue)string pattern "\d{3,}";bool b…

LLMs之RLVR:《Absolute Zero: Reinforced Self-play Reasoning with Zero Data》翻譯與解讀

LLMs之RLVR&#xff1a;《Absolute Zero: Reinforced Self-play Reasoning with Zero Data》翻譯與解讀 導讀&#xff1a;Absolute Zero范式通過讓模型在沒有外部數據的情況下&#xff0c;自主提出和解決任務&#xff0c;實現了推理能力的顯著提升。Absolute Zero Reasoner (AZ…

信息最大化(Information Maximization)

信息最大化在目標域無標簽的域自適應任務中&#xff0c;它迫使模型在沒有真實標簽的情況下&#xff0c;對未標記數據產生高置信度且類別均衡的預測。此外&#xff0c;這些預測也可以作為偽標簽用于自訓練。 例如&#xff0c;在目標域沒有標簽時&#xff0c;信息最大化損失可以…

AUTOSAR實戰教程--標準協議棧實現DoIP轉DoCAN的方法

目錄 軟件架構 關鍵知識點 第一:PDUR的緩存作用 第二:CANTP的組包拆包功能 第三:流控幀的意義 配置過程 步驟0:ECUC模塊中PDU創建 步驟1:SoAD模塊維持不變 步驟2:DoIP模塊為Gateway功能添加Connection ?步驟3:DoIP模塊為Gateway新增LA/TA/SA ?步驟4:PDUR模…

設備驅動與文件系統:05 文件使用磁盤的實現

從文件使用磁盤的實現邏輯分享 我們現在講第30講&#xff0c;內容是文件使用磁盤的具體實現&#xff0c;也就是相關代碼是如何編寫的。上一節我們探討了如何從字符流位置算出盤塊號&#xff0c;這是文件操作磁盤的核心。而這節課&#xff0c;我們將深入研究實現這一核心功能的…

【PCIe總線】-- inbound、outbound配置

PCI、PCIe相關知識整理匯總 【PCIe總線】 -- PCI、PCIe相關實現 由之前的PCIe基礎知識可知&#xff0c;pcie的組成有&#xff1a;RC&#xff08;根節點&#xff09;、siwtch&#xff08;pcie橋&#xff09;、EP&#xff08;設備&#xff09;。 RC和EP&#xff0c;以及EP和EP能…

20250607在榮品的PRO-RK3566開發板的Android13系統下實現長按開機之后出現插入適配器不會自動啟動的問題的解決

20250607在榮品的PRO-RK3566開發板的Android13系統下實現長按開機之后出現插入適配器不會自動啟動的問題的解決 2025/6/7 17:20 緣起&#xff1a; 1、根據RK809的DATASHEET&#xff0c;短按開機【100ms/500ms】/長按關機&#xff0c;長按關機。6s/8s/10s 我在網上找到的DATASHE…

AIGC 基礎篇 Python基礎 02

1.bool類型 書接上回&#xff0c;我們上次最后講了三大數據類型&#xff0c;除了這三個之外&#xff0c;Python也有bool類型&#xff0c;也就是True和False。 a 2 print(a1) print(a2) 像這里&#xff0c;輸出的內容第一個是False&#xff0c;因為a的值為2&#xff0c;而第…