如何在 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 类型,例如 Foundations 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 中将“日期”转换为“数据”,反之亦然? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Swift 中将日期转换为特定格式

无法在 Swift 中将日期格式转换为显示日期

在 Swift 中将字符串转换为日期 [重复]

如何在swift中将'Date'类型的转换值返回为'String'

如何在 Swift 5 中将文档转换为自定义对象?

在 Swift 中将日期从 GMT+1 转换为 UTC 时的困惑