使用Date.ParseStrategy解析带PDT时区日期字符串失败如何处理
问题描述
需要解析格式为 06/19/2022 01:00 PDT 的日期字符串,使用 Date.ParseStrategy(format:) 接口编写代码后运行报错,提示无法解析,输入字符串不符合指定格式,错误复现代码如下:
import Foundation let dateFromNetwork = "06/19/2022 01:00 PDT" let strategy = Date.ParseStrategy(format: "\(month: .twoDigits)/\(day: .twoDigits)/\(year: .defaultDigits) \(hour: .twoDigits(clock: .twelveHour, hourCycle: .zeroBased)):\(minute: .twoDigits)", timeZone: .init(abbreviation: "PDT")!) let date = try! Date(dateFromNetwork, strategy: strategy) // Cannot parse 06/19/2022 01:00 PDT // String should ahere to specified format, such as 06/20/2022 01:00
失败原因
解析失败由两个问题导致:
- 格式模板没有配置匹配末尾
PDT时区缩写的占位符。Date.ParseStrategy是严格全串匹配逻辑,输入字符串和模板定义的格式必须逐段对应,多出来的PDT字段会直接触发解析失败。构造方法传入的timeZone参数仅在模板未匹配到任何时区信息时作为默认兜底值使用,不会自动跳过字符串中实际存在的时区字段。 - 小时配置错误。代码中使用了12小时制的时钟配置,但输入的时间字符串没有AM/PM标识,12小时制解析逻辑无法完成时间识别。
修复方案
在格式模板末尾添加时区缩写占位符,同时将小时配置改为24小时制即可,正确代码如下:
import Foundation let dateFromNetwork = "06/19/2022 01:00 PDT" let strategy = Date.ParseStrategy( format: "\(month: .twoDigits)/\(day: .twoDigits)/\(year: .defaultDigits) \(hour: .twoDigits(clock: .twentyFourHour, hourCycle: .zeroBased)):\(minute: .twoDigits) \(timeZone: .abbreviation)", timeZone: .gmt ) let date = try! Date(dateFromNetwork, strategy: strategy)
补充说明
\(timeZone: .abbreviation)占位符支持自动识别PDT、PST、EST等常见时区缩写,无需提前硬编码时区值。- 时间配置需要和输入严格对齐:如果时间字符串带AM/PM后缀,才需要使用
.twelveHour时钟配置,同时要添加\(dayPeriod: .abbreviated)占位符匹配AM/PM字段;没有AM/PM的时间场景统一使用.twentyFourHour配置。
内容的提问来源于stack exchange,提问作者Nick Rossik
相关产品推荐
相关产品推荐

