Swift:精度与时间间隔自1970年起

Swift:精度与时间间隔自1970年起,swift,nsdate,nsdateformatter,dateformatter,swiftdate,Swift,Nsdate,Nsdateformatter,Dateformatter,Swiftdate,当我将Unix历元时间转换为毫秒时,它是四舍五入的 代码: 日志: 我以1597269862.9328开始,以1597269862.933结束。 如何将日期恢复到我开始时的状态:1597269862.9328?日期的所有组成部分(年、月、日、小时、分钟、秒等)都是整数。毫秒,顾名思义,只精确到千分之一秒(即:3位小数) 您想要得到的是纳秒属性。以下是使用Swift 5.0中添加的自定义插值功能的示例: 导入基础 扩展字符串.String插值{ ///我们的自定义日期插值器 变异函数(自定义日期:

当我将Unix历元时间转换为毫秒时,它是四舍五入的

代码:

日志:

我以
1597269862.9328
开始,以
1597269862.933
结束。 如何将日期恢复到我开始时的状态:
1597269862.9328

日期的所有组成部分(年、月、日、小时、分钟、秒等)都是整数。毫秒,顾名思义,只精确到千分之一秒(即:3位小数)

您想要得到的是
纳秒
属性。以下是使用Swift 5.0中添加的自定义插值功能的示例:

<代码>导入基础 扩展字符串.String插值{ ///我们的自定义日期插值器 变异函数(自定义日期:日期){ let组件:设置=[ .年、.月、.日、.小时、.分、.秒、.纳秒、.时区 ] 让值=Calendar.current.dateComponents(组件,从:日期) appendLiteral(values.description) } } let epochTime:TimeInterval=1597269862.9328 打印(“\(epochTime)精确的Epoch时间(注意8是最后一位数字)”) 让convertedTime=Date(时间间隔自1970年起:epochTime) 打印(“\(自定义:convertedTime)”) 结果:

1597269862.9328 Precise Epoch Time (notice the 8 is the last digit)
timeZone: America/Toronto (current) year: 2020 month: 8 day: 12 hour: 18 minute: 4 second: 22 nanosecond: 932800054 isLeapMonth: false
注意
纳秒:932800054
。此值与原始输入之间的差异是由于浮点精度造成的,这是不可避免的。

日期的所有组成部分(年、月、日、小时、分钟、秒等)都是整数。毫秒,顾名思义,只精确到千分之一秒(即:3位小数)

您想要得到的是
纳秒
属性。以下是使用Swift 5.0中添加的自定义插值功能的示例:

<代码>导入基础 扩展字符串.String插值{ ///我们的自定义日期插值器 变异函数(自定义日期:日期){ let组件:设置=[ .年、.月、.日、.小时、.分、.秒、.纳秒、.时区 ] 让值=Calendar.current.dateComponents(组件,从:日期) appendLiteral(values.description) } } let epochTime:TimeInterval=1597269862.9328 打印(“\(epochTime)精确的Epoch时间(注意8是最后一位数字)”) 让convertedTime=Date(时间间隔自1970年起:epochTime) 打印(“\(自定义:convertedTime)”) 结果:

1597269862.9328 Precise Epoch Time (notice the 8 is the last digit)
timeZone: America/Toronto (current) year: 2020 month: 8 day: 12 hour: 18 minute: 4 second: 22 nanosecond: 932800054 isLeapMonth: false

注意
纳秒:932800054
。此值与原始输入之间的差异是由于浮点精度造成的,这是不可避免的。

存在的问题是
DateFormatter
被限制为毫秒。使用它无法显示超过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.SSSSSSSSSXXXXX"
        return formatter
    }()
}

如果要恢复初始值,只需从转换的时间日期中获取时间间隔:

let epochTime: TimeInterval = 1597269862.9328
print("\(epochTime) Precise Epoch Time")

let convertedTime = Date(timeIntervalSince1970: epochTime)
print("\(convertedTime) Time converted To Swift Date")

print(convertedTime.timeIntervalSince1970)   // "1597269862.9328\n"

请注意,Swift
Date
存储为自参考日期起的时间间隔。如果要保留日期准确性,则在存档时应使用timeIntervalSinceReferenceDate而不是timeIntervalSince1970。检查此项。

存在的问题是
DateFormatter
限制为毫秒。使用它无法显示超过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.SSSSSSSSSXXXXX"
        return formatter
    }()
}

如果要恢复初始值,只需从转换的时间日期中获取时间间隔:

let epochTime: TimeInterval = 1597269862.9328
print("\(epochTime) Precise Epoch Time")

let convertedTime = Date(timeIntervalSince1970: epochTime)
print("\(convertedTime) Time converted To Swift Date")

print(convertedTime.timeIntervalSince1970)   // "1597269862.9328\n"

请注意,Swift
Date
存储为自参考日期起的时间间隔。如果要保留日期准确性,则在存档时应使用timeIntervalSinceReferenceDate而不是timeIntervalSince1970。检查此项。

谢谢。如何提取最终值1597269862.9328或1597269862.932800054。?DateComponents中没有毫秒分量。date属性timeIntervalSince1970不限于毫秒。它具有相同的纳秒精度。唯一丢失的精度(与此问题无关)是由于以下事实造成的:引擎盖下的日期存储为自参考日期起的时间间隔。谢谢如何提取最终值1597269862.9328或1597269862.932800054。?DateComponents中没有毫秒分量。date属性timeIntervalSince1970不限于毫秒。它具有相同的纳秒精度。唯一丢失的精度(与此问题无关)是由于以下事实造成的:引擎盖下的日期存储为自参考日期起的时间间隔@用户1107173使用
DateFormatter
和/或
ISO8601DateFormatter
@user1107173没有标准方法将日期转换为字符串并返回日期,保留第三个数字后的小数位数使用
DateFormatter
和/或
ISO8601DateFormatter