【问题标题】:Convert DATA to Date将数据转换为日期
【发布时间】:2020-05-21 08:17:22
【问题描述】:

我正在尝试使用 NSFileManager 获取文件的最后使用日期,我正在获取 NSData 格式的日期,但我不确定如何将数据转换为日期。

我从 NSFileManager 得到的值低于

key : "com.apple.lastuseddate#PS"
value : <b9b6c35e 00000000 abd73225 00000000>

请告诉我如何将上述数据值转换为日期。

我使用下面的函数将数据转换为日期,但我得到的值完全错误。

func dataToDate(data:Data) -> Date{
    let components = NSDateComponents()
    let bytes = [uint8](data)
    components.year   = Int(bytes[0] | bytes[1] << 8)
    components.month  = Int(bytes[2])
    components.day    = Int(bytes[3])
    components.hour   = Int(bytes[4])
    components.minute = Int(bytes[5])
    components.second = Int(bytes[6])

    let calendar = NSCalendar.current
    return calendar.date(from: components as DateComponents)!
}

编辑: @Martin R,下面是我用来获取数据的代码。

var attributes:[FileAttributeKey : Any]?
do{
    attributes = try FileManager.default.attributesOfItem(atPath: url.path)
}catch{
    print("Issue getting attributes of file")
}

if let extendedAttr = attributes![FileAttributeKey(rawValue: "NSFileExtendedAttributes")] as? [String : Any]{
    let data = extendedAttr["com.apple.lastuseddate#PS"] as? Data
}

【问题讨论】:

  • 如果数据只有几个字节,你能打印数据的各个字节吗?这样我们可以尝试找出数据的格式。也就是说,您可以随时尝试NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! Date
  • 查看this 文章。基本上,您可以使用JSONDecder 并将其dateDecodingStrategy 设置为适当的值。
  • @Sweeper:你可以在value : &lt;b9b6c35e 00000000 abd73225 00000000&gt;看到各个字节
  • @MartinR 这是一种令人困惑的字节写入方式……他们为什么要这样分组?我完全认为这是某种地址...
  • @Sweeper:这就是 NSData 在 Objective-C 中的打印方式。我假设实际值是 NSData 但桥接到 Data for Swift。 – 地址将有 8 个字节,而不是 16 个。

标签: swift macos nsdate nsdata


【解决方案1】:

可以在 Apple 开发者论坛的Data to different types ? 中找到必要的信息。

首先请注意,依赖未记录的扩展属性是不安全的。获得相同结果的更好方法是从NSMetadataItem 中检索NSMetadataItemLastUsedDateKey

if let date = NSMetadataItem(url: url)?.value(forAttribute: NSMetadataItemLastUsedDateKey) as? Date {
    print(date)
}

但是要回答您的实际问题:该扩展属性具有 UNIX struct timespec(比较 &lt;time.h&gt;)值。这是用于st_atimespecstruct stat 的其他成员的类型(这又是用于fstat() 和类似系统调用的类型)。

您必须将数据复制到timespec 值中,根据tv_sectv_nsec 成员计算秒数,然后根据自Unix 纪元以来的秒数创建Date

func dataToDate(data: Data) -> Date {
    var ts = timespec()
    precondition(data.count >= MemoryLayout.size(ofValue: ts))
    _ = withUnsafeMutableBytes(of: &ts, { lastuseddata.copyBytes(to: $0)} )
    let seconds = TimeInterval(ts.tv_sec) + TimeInterval(ts.tv_nsec)/TimeInterval(NSEC_PER_SEC)
    return Date(timeIntervalSince1970: seconds)
}

示例(您的数据):

let lastuseddata = Data([0xb9, 0xb6, 0xc3, 0x5e, 0x00, 0x00, 0x00, 0x00,
                         0xab, 0xd7, 0x32, 0x25, 0x00, 0x00, 0x00, 0x00])

print(dataToDate(data: lastuseddata))
// 2020-05-19 10:36:41 +0000

【讨论】:

  • 感谢您的精彩回答。我使用了 NSMetadataItem(url: url)?正如你提到的,我能够得到最后使用的日期。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多