Swift 可变日期时间字符串的日期格式

Swift dateFormat for variable dateType strings

我正在尝试解析一些 json 这是 oData 连接的结果,我从服务器收到以下响应:

"Task_ID":24,"Equipment_ID":3,"Owner_ID":2,"Priority":5,"Date_Due":
"2015-04-08T19:37:56.913","Time_Complete":"2015-04-09T19:37:56","Task_Description"

我实际上对收到的两个不同日期字段感兴趣:

"Date_Due":"2015-04-08T19:37:56.913"


"Time_Complete":"2015-04-09T19:37:56"

我们可以看到,一个有毫秒时间戳,一个没有。

通过查看数据库,发生这种情况是因为在数据库(MS SQL 服务器)中毫秒实际上是 .000,并且出于某种原因,我在 json 中收到的结果是这样的部分被截断。

我对毫秒不感兴趣,但我想要一个可以处理这两种情况的 dateFormat 函数。

现在我有一个明显的答案,即(预)解析每个日期字段,删除毫秒(如果存在)然后使用以下代码对其进行格式化:

let SQLDateFormatter: NSDateFormatter = {
    let formatter = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
    formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0)
    return formatter
}()

但是我想知道我们是否可以构建一个无需预解析就可以解决此问题的格式化程序,它可以兼顾两者:

formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"

formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"

并自动正确格式化。

我一直在检查这个问题,但找不到任何东西,在此先感谢...

否,如果字符串不符合指定的确切日期格式,NSDateFormatter 将 return 为 nil。

你可以做的不是预处理字符串,而是检查你得到的字符串是否有毫秒。

执行此操作的最佳方法是使用正则表达式。这个想法是像平常一样创建 SQLDateFormatter,然后检查字符串是否有毫秒。如果包含毫秒,只需更改日期格式 - 比解析字符串更好。

if let match = tes.rangeOfString("(\d{4}-\d\d-\d\d[T](\d\d:){2}\d\d.\d{3})", options: NSStringCompareOptions.RegularExpressionSearch)
{
    SQLDateFormatter.format = "yyyy-MM-dd'T'HH:mm:ss.SSS"
}
extension Formatter {
    static let iso8601: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        return formatter
    }()
    static let iso8601withFractionalSeconds: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        return formatter
    }()
}

extension String {
    var date: Date? {
       return Formatter.iso8601withFractionalSeconds.date(from: self) ??
            Formatter.iso8601.date(from: self)
    }
}

"2015-04-08T19:37:56.913".date  // "Apr 8, 2015, 4:37 PM"
"2015-04-09T19:37:56".date      // "Apr 9, 2015, 4:37 PM"