Swift DateFormatter可选毫秒 [英] Swift DateFormatter Optional Milliseconds

查看:770
本文介绍了Swift DateFormatter可选毫秒的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码来解析ISO8601日期。

I have the following code to parse an ISO8601 date.

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"

问题是有时日期格式为 2018-01-21T20:11:20.057Z ,有时格式为 2018-01- 21T20:11:20Z

Problem is sometimes the date is in a format like 2018-01-21T20:11:20.057Z, and other times it's in a format like 2018-01-21T20:11:20Z.

所以基本上它的部分时间是 .SSS 毫秒部分,有时则没有。

So basically part of the time it has the .SSS millisecond part, and other times it does not.

如何设置日期格式化程序以使该部分可选?

How can I setup the date formatter to make that part optional?

编辑

我忘了在我刚才意识到的问题中提到一些细节。所以我在Swift 4中使用了JSON Codable功能。所以如果失败就会抛出错误。

I forgot to mention a few details tho in my question I just realized. So I'm using the JSON Codable feature in Swift 4. So it just throws an error if it fails.

所以我基本上有以下代码。

So I basically have the following code.

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(isoMilisecondDateFormatter())

return try decoder.decode([Person].self, from: _people)

_people 的示例JSON对象是以下。

An example JSON object for _people is the following.

[
    {
        "name": "Bob",
        "born": "2018-01-21T20:11:20.057Z"
    },
    {
        "name": "Matt",
        "born": "2018-01-21T20:11:20Z"
    }
]

API我是使用是非常不一致所以我必须处理多种类型的数据。

The API I'm working with is pretty inconsistent so I have to deal with multiple types of data.

推荐答案

两个建议:


  • 使用包含毫秒的日期格式转换字符串。如果它返回 nil 将其转换为其他格式。

  • Convert the string with the date format including the milliseconds. If it returns nil convert it with the other format.

使用Regular从字符串中删除毫秒表达式:

Strip the milliseconds from the string with Regular Expression:

var dateString = "2018-01-21T20:11:20.057Z"
dateString = dateString.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)
// -> 2018-01-21T20:11:20Z


修改

要与 Codable 一起使用,您必须编写自定义初始值设定项,指定 dateDecodingStrategy 不起作用

To use it with Codable you have to write a custom initializer, specifying dateDecodingStrategy does not work

struct Foo: Decodable {
    let birthDate : Date
    let name : String

    private enum CodingKeys : String, CodingKey { case born, name }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        var rawDate = try container.decode(String.self, forKey: .born)
        rawDate = rawDate.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)
        birthDate = ISO8601DateFormatter().date(from: rawDate)!
        name = try container.decode(String.self, forKey: .name)
    }
}







let jsonString = """
[{"name": "Bob", "born": "2018-01-21T20:11:20.057Z"}, {"name": "Matt", "born": "2018-01-21T20:11:20Z"}]
"""

do {
    let data = Data(jsonString.utf8)
    let result = try JSONDecoder().decode([Foo].self, from: data)
    print(result)
} catch {
    print("error: ", error)
}

这篇关于Swift DateFormatter可选毫秒的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆