iOS Date()返回日期的精度至少为微秒。 我通过调用Date().timeIntervalSince1970导致1490891661.074981
Date()
Date().timeIntervalSince1970
1490891661.074981
然后,我需要将日期转换为微秒精度的字符串。 我使用DateFormatter以下方式:
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"
"2017-03-30T16:34:21.075000Z"
现在,如果我们比较两个结果: 1490891661.074981并且"2017-03-30T16:34:21.075000Z" 我们可以注意到将DateFormatter日期舍入为毫秒精度,同时仍然以微秒为单位显示零。
有人知道如何配置,DateFormatter以便我可以保持微秒并获得正确的结果"2017-03-30T16:34:21.074981Z"吗?
"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