将要通过网络发送/接收的日期(绝对时间)转换为Swift中的数据?

问题描述 投票:0回答:3

我正在寻找一种快速生成时间戳的方法。

我的macOS应用记录了一些数据,并在创建数据时标记它们。然后,数据将通过网络发送(作为Data)以在iPad上重建。

是否有任何Swift类可用于生成时间戳? NSDate? NSTimeIntervalSince1970? CFAbsoluteTimeGetCurrent()

要求是:

  1. 将时间戳记存储在尽可能少的字节中(首选Int
  2. 与真实的地球时间有些相似(我宁愿不产生我的自己的时间格式)
  3. 毫秒精度
  4. 快速构建
  5. iOS 9 +,macOS 10.10 +
swift timestamp nsdate nstimeinterval
3个回答
2
投票

您可以发送Date,将其转换为Data(8字节浮点数,然后返回到Date,如下所示:

extension Numeric {
    var data: Data {
        var source = self
        return Data(bytes: &source, count: MemoryLayout<Self>.size)
    }
    init<D: DataProtocol>(_ data: D) {
        var value: Self = .zero
        let size = withUnsafeMutableBytes(of: &value, { data.copyBytes(to: $0)} )
        assert(size == MemoryLayout.size(ofValue: value))
        self = value
    }
}

extension DataProtocol {
    func value<N: Numeric>() -> N { .init(self) }
    var date: Date { .init(data: self) }
}

extension Date {
    var data: Data { timeIntervalSinceReferenceDate.bitPattern.littleEndian.data }
    init<D: DataProtocol>(data: D) {
        self.init(timeIntervalSinceReferenceDate: .init(bitPattern: .init(littleEndian: data.value())))
    }
}

操场测试

let date = Date()            // "Nov 15, 2019 at 12:13 PM"
let data = date.data         // 8 bytes
print(Array(data))           // "[25, 232, 158, 22, 124, 191, 193, 65]\n"
let loadedDate = data.date   // "Nov 15, 2019 at 12:13 PM"
print(date == loadedDate)    // "true\n"

0
投票

这是我使用Leo Dabus的答案的方式。

public struct Timestamp: Equatable, Comparable {

    public let date: Date

    public init() {
        self.date = Date()
    }

    public func toData() -> Data {
        var date = self.date
        return Data(bytes: &date, count: MemoryLayout<Date>.size)
    }

    public init(fromData data: Data) {
        guard data.count == 8 else {
            fatalError("Insufficient bytes. expected 8; got \(data.count). data: \(data)")
        }
        self.date = data.withUnsafeBytes { $0.pointee }
    }

    public static func ==(lhs: Timestamp, rhs: Timestamp) -> Bool {
        return lhs.date == rhs.date
    }

    public static func <(lhs: Timestamp, rhs: Timestamp) -> Bool {
        return lhs.date < rhs.date
    }
}

0
投票

使用TimeIntervalSince1970类型:

let exactTimeInMilliseconds = Date().timeIntervalSince1970

原始答案非常无效。

© www.soinside.com 2019 - 2024. All rights reserved.