如何创建日期时间戳和格式为ISO 8601,RFC 3339,UTC时区? [英] How to create a date time stamp and format as ISO 8601, RFC 3339, UTC time zone?
问题描述
目标是一个看起来像这样的字符串:
The goal is a string that looks like this:
"2015-01-01T00:00:00.000Z"
格式:
- 年,月,日为"XXXX-XX-XX"
- 字母"T"作为分隔符
- 小时,分钟,秒和毫秒,如"XX:XX:XX.XXX".
- 字母"Z"作为零偏移的区域标记,又称UTC,GMT,祖鲁时间.
最佳情况:
- 快速,简单,简短的源代码.
- 无需使用任何其他框架,子项目,cocoapod,C代码等.
我已经搜索了StackOverflow,Google,Apple等,但没有找到Swift的答案.
I've searched StackOverflow, Google, Apple, etc. and haven't found a Swift answer to this.
看起来最有前途的类是 NSDate
, NSDateFormatter
,> c2> .
The classes that seem most promising are NSDate
, NSDateFormatter
, NSTimeZone
.
相关问答:如何获得ISO 8601在iOS中约会?
这是到目前为止我想出的最好的方法:
Here's the best I've come up with so far:
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, timeZone: TimeZone = TimeZone(secondsFromGMT: 0)!) {
self.init()
self.formatOptions = formatOptions
self.timeZone = timeZone
}
}
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) }
}
用法:
Usage:
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时需要对这种格式进行编码和解码 协议,您可以创建自己的自定义日期编码/解码策略:
If you need to encode and decode this format when working with Codable protocol you can create your own custom date encoding/decoding strategies:
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))
}
}
游乐场测试
Playground Testing
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"]
这篇关于如何创建日期时间戳和格式为ISO 8601,RFC 3339,UTC时区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!