如何在 Swift 5 中将“日期”转换为“数据”,反之亦然? [复制]
Posted
技术标签:
【中文标题】如何在 Swift 5 中将“日期”转换为“数据”,反之亦然? [复制]【英文标题】:How to convert `Date` to `Data`, and vice versa in Swift 5? [duplicate] 【发布时间】:2021-09-13 07:52:13 【问题描述】:我正在尝试在 Keychain 中保存日期,并且(据我了解)这首先需要将 Date
对象转换为 Data
对象。
This Stack Overflow Q/A 解释了如何在 Swift 3 中实现(或至少部分实现),但我希望有人可以在 Swift 5 中提供 to/from 函数(因为该解决方案中至少有一种方法已被弃用,我担心其他东西也没有经受住时间的考验)。
【问题讨论】:
简单方法:由于Date
只是一个具有时间戳(自参考日期1970年以来的秒数)的高级方法的对象,只需获取该时间时间戳(它是一个双精度数),并对其进行转换进入Data
。见***.com/questions/38023838/… ?
@Larme 我喜欢它。谢谢。
@Eric 查看这篇文章,了解如何正确地将日期转换为数据并保留其纳秒和字节序。 ***.com/a/47502712/2303865
A Date value encapsulate a single point in time, independent of any particular calendrical system or time zone. Date values represent a time interval relative to an absolute reference date
【参考方案1】:
Date
是一个时间戳(自 1970 年 UTC 参考日期以来的秒数)作为具有花哨方法和其他实用程序的对象。仅此而已。
所以基于the answer Double to Data(和反向):
输入
let date = Date()
print(date)
日期 -> 时间戳 -> 数据
let timestamp = date.timeIntervalSinceReferenceDate
print(timestamp)
let data = withUnsafeBytes(of: timestamp) Data($0)
print("\(data) - \(data.map String(format: "%02hhx", $0) .joined())")
数据 -> 时间戳 -> 日期
let retrievedTimestamp = data.withUnsafeBytes $0.load(as: Double.self)
print(retrievedTimestamp)
let retrievedDate = Date(timeIntervalSinceReferenceDate: retrievedTimestamp)
print(retrievedDate)
输出:
$>2021-09-13 08:17:50 +0000
$>1631521070.6852288
$>8 bytes - cadaab4bc24fd841
$>1631521070.6852288
$>2021-09-13 08:17:50 +0000
【讨论】:
最好使用 timeIntervalSinceReferenceDate。如果您从 1970 年开始使用,则无法保证如果您将其转换回日期,它将是完全相同的日期。 不一样吗?只有“30 年”的偏移量,不是吗? 这不会像使用timeIntervalSinceReferenceDate
那样精确。这就是它在引擎盖下的存储方式。检查这篇文章。 ***.com/a/47502712/2303865
A Date value encapsulate a single point in time, independent of any particular calendrical system or time zone. Date values represent a time interval relative to an absolute reference date【参考方案2】:
执行此操作的“更安全”(但效率较低)的方法是使用 Encoder
/Decoder
类型,例如 Foundation
s JSONEncoder
/JSONDecoder
。
如果数据以某种方式损坏,这些类型将抛出Error
,而不是陷入陷阱。
您只需要确保每个日期编码/解码策略相同即可。
let myDate = Date()
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .secondsSince1970
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
// TODO: handle errors correctly
let dateData = try! encoder.encode(myDate)
let retrievedDate = try! decoder.decode(Date.self, from: dateData)
assert(myDate == retrievedDate)
【讨论】:
以上是关于如何在 Swift 5 中将“日期”转换为“数据”,反之亦然? [复制]的主要内容,如果未能解决你的问题,请参考以下文章