You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java DateTimeFormatter解析挪威语短月份日期失败问题

问题原因分析

核心原因

Java 中挪威语 Locale(如 nb-NO)对应的月份短格式(MMM)默认包含句点后缀。以四月为例,TextStyle.SHORT 对应的缩写是 apr.,而非你输入中的 apr(无句点)。

当你使用模式 d. MMM yyyy HH:mm 解析 8. apr 2024 15:32 时,解析器会在索引3的位置(apr 起始处)期望匹配带句点的月份缩写,但输入中没有句点,直接导致匹配失败,抛出 DateTimeParseException。

而尝试用 d. MMM. yyyy HH:mm 解析 8. apr. 2024 15:32 时,模式中的 MMM. 会要求匹配 apr..(因为 MMM 本身对应 apr.,额外的句点会叠加),但输入仅为 apr.,同样无法匹配,引发异常。

验证方式

你可以通过以下代码打印挪威语 Locale 下的月份短缩写,确认默认格式:

import java.time.Month;
import java.time.format.TextStyle;
import java.util.Locale;

public class TestMonthAbbr {
    public static void main(String[] args) {
        Locale norwegian = Locale.forLanguageTag("nb");
        for (Month month : Month.values()) {
            System.out.println(month.getDisplayName(TextStyle.SHORT, norwegian));
        }
    }
}

输出的四月缩写会是 apr.,带句点后缀。

解决思路

  1. 调整输入字符串:如果可控,将输入中的月份缩写改为带句点的格式(如 apr.),直接使用 d. MMM yyyy HH:mm 模式即可解析。
  2. 自定义月份解析规则:通过 DateTimeFormatterBuilder 手动映射无句点的月份缩写,示例如下:
import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

public class DateParser {
    public static LocalDateTime parseDatoLocalDateTime2(String datoString, String language) {
        // 针对挪威语无句点的月份缩写自定义映射
        Map<String, Month> monthMap = new HashMap<>();
        monthMap.put("jan", Month.JANUARY);
        monthMap.put("feb", Month.FEBRUARY);
        monthMap.put("mar", Month.MARCH);
        monthMap.put("apr", Month.APRIL);
        monthMap.put("mai", Month.MAY);
        monthMap.put("jun", Month.JUNE);
        monthMap.put("jul", Month.JULY);
        monthMap.put("aug", Month.AUGUST);
        monthMap.put("sep", Month.SEPTEMBER);
        monthMap.put("okt", Month.OCTOBER);
        monthMap.put("nov", Month.NOVEMBER);
        monthMap.put("des", Month.DECEMBER);

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .appendPattern("d. ")
                .appendText(ChronoField.MONTH_OF_YEAR, monthMap) // 使用自定义映射
                .appendPattern(" yyyy HH:mm")
                .toFormatter(Locale.forLanguageTag(language));
        return LocalDateTime.parse(datoString, formatter);
    }
}
  1. 使用宽松解析(谨慎使用):添加 parseLenient() 配置,但这种方式可能会引入意外的匹配逻辑,仅在确保输入格式稳定的场景下使用:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .parseLenient()
        .appendPattern(pattern)
        .toFormatter(Locale.forLanguageTag(language));

内容的提问来源于stack exchange,提问作者kakemonsteret

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:36:02