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

使用Europe/Sofia时区时DateFormatter无法解析1995-03-26日期的原因

DateFormatter解析日期异常:Europe/Sofia时区下1995-03-26无法解析的原因

问题场景

使用DateFormatter解析后端返回的日期字符串时,发现当时区设置为"Europe/Sofia"时,无法从"1995-03-26"初始化日期;切换为固定GMT+2时区或其他日期(如1995-03-25、1995-03-27)则解析正常。测试代码如下:

import Foundation

let serverLocalDateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "yyyy-MM-d"
    formatter.timeZone = TimeZone(secondsFromGMT: 60 * 60 * 2)
    
    return formatter
}()

let serverLocalDateFormatter2: DateFormatter = {
    let formatter = DateFormatter()
    
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.dateFormat = "yyyy-MM-d"
    formatter.timeZone = TimeZone(identifier: "Europe/Sofia")
    
    return formatter
}()

let testCase1 = "1995-03-26"
let testCase2 = "1995-03-27"
let testCase3 = "1995-03-25"

serverLocalDateFormatter.date(from: testCase1)
serverLocalDateFormatter2.date(from: testCase1)
serverLocalDateFormatter.date(from: testCase2)
serverLocalDateFormatter.date(from: testCase3)

异常原因

问题核心在于Europe/Sofia时区1995年的夏令时切换规则:

  • 1995年3月26日是保加利亚夏令时启动的日期,当地时间在3月25日23:00结束后,直接跳转到3月26日01:00,跳过了26日00:00到00:59:59的整个时间段。
  • DateFormatter解析仅含日期的字符串时,会默认补充时间为00:00:00。由于这个时间点在Europe/Sofia时区中不存在,date(from:)方法无法生成有效的Date实例,因此返回nil。
  • 使用固定GMT+2时区的格式化器可以解析,是因为它不考虑时区的夏令时历史变更,直接将"1995-03-26"视为GMT+2时区的00:00,对应的UTC时间为1995-03-25 22:00:00,这是一个真实存在的有效时间点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 11:34:54