微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

swift – 如何配置DateFormatter以捕获微秒

iOS Date()以至少微秒的精度返回日期.
我通过调用Date().timeIntervalSince1970检查了这个语句,结果是1490891661.074981

然后我需要将日期转换为具有微秒精度的字符串.
我以下列方式使用DateFormatter:

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ"
print(formatter.string(from: date))

结果
“2017-03-30T16:34:21.075000Z”

现在,如果我们比较两个结果:
1490891661.074981和“2017-03-30T16:34:21.075000Z”
我们可以注意到DateFormatter将日期舍入到毫秒精度,同时仍然呈现零微秒.

有没有人知道如何配置DateFormatter所以我可以保持微秒并得到正确的结果:“2017-03-30T16:34:21.074981Z”?

解决方法

感谢@MartinR解决了我的问题的前半部分,感谢@ForestKunecke为我提供了如何解决问题后半部分的提示.

基于他们的帮助,我创建了可立即使用的解决方案,该解决方案从字符串转换日期,反之亦然,精确到毫秒:

public final class MicrosecondPrecisionDateFormatter: DateFormatter {

    private let microsecondsPrefix = "."

    override public init() {
        super.init()
        locale = Locale(identifier: "en_US_POSIX")
        timeZone = TimeZone(secondsFromGMT: 0)
    }

    required public init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override public func string(from date: Date) -> String {
        dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
        let components = calendar.dateComponents(Set([Calendar.Component.nanosecond]),from: date)

        let nanosecondsInMicrosecond = Double(1000)
        let microseconds = lrint(Double(components.nanosecond!) / nanosecondsInMicrosecond)

        // Subtract nanoseconds from date to ensure string(from: Date) doesn't attempt faulty rounding.
        let updatedDate = calendar.date(byAdding: .nanosecond,value: -(components.nanosecond!),to: date)!
        let dateTimeString = super.string(from: updatedDate)

        let string = String(format: "%@.%06ldZ",dateTimeString,microseconds)

        return string
    }

    override public func date(from string: String) -> Date? {
        dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"

        guard let microsecondsPrefixrange = string.range(of: microsecondsPrefix) else { return nil }
        let microsecondsWithTimeZonestring = String(string.suffix(from: microsecondsPrefixrange.upperBound))

        let nonDigitsCharacterSet = CharacterSet.decimalDigits.inverted
        guard let timeZoneRangePrefixrange = microsecondsWithTimeZonestring.rangeOfCharacter(from: nonDigitsCharacterSet) else { return nil }

        let microsecondsstring = String(microsecondsWithTimeZonestring.prefix(upTo: timeZoneRangePrefixrange.lowerBound))
        guard let microsecondsCount = Double(microsecondsstring) else { return nil }

        let dateStringExludingMicroseconds = string
            .replacingOccurrences(of: microsecondsstring,with: "")
            .replacingOccurrences(of: microsecondsPrefix,with: "")

        guard let date = super.date(from: dateStringExludingMicroseconds) else { return nil }
        let microsecondsInSecond = Double(1000000)
        let dateWithMicroseconds = date + microsecondsCount / microsecondsInSecond

        return dateWithMicroseconds
    }
}

用法

let formatter = MicrosecondPrecisionDateFormatter()
let date = Date(timeIntervalSince1970: 1490891661.074981)
let formattedString = formatter.string(from: date) // 2017-03-30T16:34:21.074981Z

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐