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

Kotlin解析俄文日期失败:如何正确解析"28 фев. 2019"?

俄文日期解析失败问题排查与解决

问题描述

尝试用Kotlin代码解析多语言日期格式时,俄文日期"27 апр. 2018"和"24 мая. 2013"能正常解析,但"28 фев. 2019"始终解析失败。运行环境为Java 17.0.4.1,报错信息如下:

Parse failed - java.time.format.DateTimeParseException: Text '28 фев. 2019' could not be parsed at index 3

用户核心代码示例:

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.*

println("System.getProperty - " + System.getProperty("java.version"));
println("Runtime.version - " + Runtime.version());

val dateString = "28 фев. 2019"

sequenceOf(
    "ru-RU", // Russian
    "sr", // Serbian
).forEach {
    val format = DateTimeFormatter.ofPattern("d MMM. yyyy")
        .withLocale(Locale.forLanguageTag(it))
    try {
        println("Parse successful - " + LocalDate.parse(dateString, format))
    } catch (e: Exception) {
        println("Parse failed - " + e)
    }
}

问题原因

俄语中“二月”的标准缩写在Java的DateTimeFormatter默认配置里是"февр."(4个字母加句号),但待解析的日期里用的是"фев."(3个字母加句号),两者长度不匹配,导致解析失败。而其他月份(如四月апр.、五月мая.)的缩写与系统默认值一致,所以能正常解析。

解决方案

方案一:自定义月份缩写映射

创建包含目标缩写的映射表,覆盖DateTimeFormatter的默认月份解析规则:

import java.time.LocalDate
import java.time.Month
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeFormatterBuilder
import java.util.*

fun main() {
    println("System.getProperty - " + System.getProperty("java.version"))
    println("Runtime.version - " + Runtime.version())

    val dateString = "28 фев. 2019"
    val ruLocale = Locale.forLanguageTag("ru-RU")

    // 自定义俄文月份缩写与对应月份的映射
    val monthAbbrMap = mapOf(
        "янв." to Month.JANUARY,
        "фев." to Month.FEBRUARY,
        "мар." to Month.MARCH,
        "апр." to Month.APRIL,
        "мая." to Month.MAY,
        "июн." to Month.JUNE,
        "июл." to Month.JULY,
        "авг." to Month.AUGUST,
        "сен." to Month.SEPTEMBER,
        "окт." to Month.OCTOBER,
        "ноя." to Month.NOVEMBER,
        "дек." to Month.DECEMBER
    )

    val formatter = DateTimeFormatterBuilder()
        .appendPattern("d ")
        .appendText(Month.MONTH_OF_YEAR, monthAbbrMap)
        .appendPattern(" yyyy")
        .toFormatter(ruLocale)

    try {
        println("Parse successful - " + LocalDate.parse(dateString, formatter))
    } catch (e: Exception) {
        println("Parse failed - " + e)
    }
}

方案二:启用宽松解析模式

通过DateTimeFormatterBuilder设置宽松解析,允许部分匹配系统默认的缩写:

import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeFormatterBuilder
import java.util.*

fun main() {
    println("System.getProperty - " + System.getProperty("java.version"))
    println("Runtime.version - " + Runtime.version())

    val dateString = "28 фев. 2019"
    val ruLocale = Locale.forLanguageTag("ru-RU")

    val formatter = DateTimeFormatterBuilder()
        .appendPattern("d MMM. yyyy")
        .parseLenient() // 启用宽松解析规则
        .toFormatter(ruLocale)

    try {
        println("Parse successful - " + LocalDate.parse(dateString, formatter))
    } catch (e: Exception) {
        println("Parse failed - " + e)
    }
}

注意:宽松解析可能引入歧义风险,若存在其他类似缩写的日期格式,需谨慎使用。

运行验证

使用方案二的代码运行后,输出结果为:

System.getProperty - 17.0.4.1
Runtime.version - 17.0.4.1+7-b469.62
Parse successful - 2019-02-28

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:50:49