如何将 IAP 日期转换为日期?

How to convert IAP dates to Date?

我正在尝试解析 IAP 收据信息中的日期。

Apple says 它们“采用类似于 ISO 8601 的日期时间格式”。

但是,当我设置 decoder.dateDecodingStrategy = .iso8601 时,出现以下解码错误:Expected date string to be ISO8601-formatted..

你如何解析这些日期?

(不知道为什么 Apple 不提供正确的 ISO 8601 日期。)

您可以为解码器使用自定义格式化程序,但您需要决定要使用哪个版本的日期字段,因为每个日期都以 GMT 时间、PST 时间和毫秒表示。

"original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
"original_purchase_date_ms": "1375340400000",
"original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",

以下是 3 种不同的解决方案,但您需要注意,因为您只能对所有日期使用其中一种。

如果您想使用像 original_purchase_date 这样的 GMT 版本,您可以使用具有这种格式和时区的日期格式化程序

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss 'Etc/'zzz"

(请注意,我不确定这是否始终是格林威治标准时间,我是基于样本收据,但它应该适用于任何适当的时区缩写)

或对于 PST 版本,original_purchase_date_pst

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss 'America/Los_Angeles'"

然后将格式化程序与您的解码器一起使用

decoder.dateDecodingStrategy = .formatted(formatter)

您还可以通过使用 .custom 选项为 original_purchase_date_ms 变体

解码器使用毫秒的第三个选项
struct InvalidTimestampError: Error {}

decoder.dateDecodingStrategy = .custom { decoder in
    let container = try decoder.singleValueContainer()
    let string = try container.decode(String.self)
    guard let value = Double(string) else {
        throw InvalidTimestampError()
    }

    return Date(timeIntervalSince1970: value / 1000)        
}