如何使用ISO 8601和RFC 3339的格式标准生成日期时间戳?
目标是一个如下所示的字符串:
"2015-01-01T00:00:00.000Z"
格式:
最佳案例:
我搜索了 StackOverflow、Google、Apple 等,但没有找到 Swift 的答案。
看起来最有希望的类是NSDate, NSDateFormatter, NSTimeZone。
NSDate
NSDateFormatter
NSTimeZone
相关问答:如何在 iOS 上获取 ISO 8601 日期?
这是迄今为止我想出的最好的:
var now = NSDate() var formatter = NSDateFormatter() formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) println(formatter.stringFromDate(now))
Swift 4——iOS 11.2.1 或更高版本
extension ISO8601DateFormatter { convenience init(_ formatOptions: Options) { self.init() self.formatOptions = formatOptions } }
extension Formatter { static let iso8601withFractionalSeconds = ISO8601DateFormatter([.withInternetDateTime, .withFractionalSeconds]) }
extension Date { var iso8601withFractionalSeconds: String { return Formatter.iso8601withFractionalSeconds.string(from: self) } }
extension String { var iso8601withFractionalSeconds: Date? { return Formatter.iso8601withFractionalSeconds.date(from: self) } }
用法:
Date().description(with: .current) // Tuesday, February 5, 2019 at 10:35:01 PM Brasilia Summer Time" let dateString = Date().iso8601withFractionalSeconds // "2019-02-06T00:35:01.746Z" if let date = dateString.iso8601withFractionalSeconds { date.description(with: .current) // "Tuesday, February 5, 2019 at 10:35:01 PM Brasilia Summer Time" print(date.iso8601withFractionalSeconds) // "2019-02-06T00:35:01.746Z\n" }
iOS 9 - Swift 3 或更高版本
extension Formatter { static let iso8601withFractionalSeconds: DateFormatter = { let formatter = DateFormatter() formatter.calendar = Calendar(identifier: .iso8601) formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = TimeZone(secondsFromGMT: 0) formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX" return formatter }() }
可编码协议 如果您在使用 Codable 协议时需要对这种格式进行编码和解码,您可以创建自己的自定义日期编码/解码策略:
可编码协议
如果您在使用 Codable 协议时需要对这种格式进行编码和解码,您可以创建自己的自定义日期编码/解码策略:
extension JSONDecoder.DateDecodingStrategy { static let iso8601withFractionalSeconds = custom { let container = try $0.singleValueContainer() let string = try container.decode(String.self) guard let date = Formatter.iso8601withFractionalSeconds.date(from: string) else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date: " + string) } return date } }
和编码策略
extension JSONEncoder.DateEncodingStrategy { static let iso8601withFractionalSeconds = custom { var container = $1.singleValueContainer() try container.encode(Formatter.iso8601withFractionalSeconds.string(from: $0)) } }
游乐场测试
let dates = [Date()] // ["Feb 8, 2019 at 9:48 PM"]
编码
let encoder = JSONEncoder() encoder.dateEncodingStrategy = .iso8601withFractionalSeconds let data = try! encoder.encode(dates) print(String(data: data, encoding: .utf8)!)
解码
let decoder = JSONDecoder() decoder.dateDecodingStrategy = .iso8601withFractionalSeconds let decodedDates = try! decoder.decode([Date].self, from: data) // ["Feb 8, 2019 at 9:48 PM"]