I'm trying to parse a date and time with microseconds using DateFormatter. However the obtained instance of Date class holds the time rounded off to milliseconds.
I can show it with this code:
import Foundation
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS"
let date = formatter.date(from: "2022-02-01T19:35:49.987654")!
print(formatter.string(from: date))
print(Calendar.current.component(.nanosecond, from: date))
The output is:
2022-02-01T19:35:49.987000
986999988
So 987654 microseconds were rounded off to 987 milliseconds and I don't understand why.
What am I doing wrong and how to fix it?
Thanks in advance.
P.S. swift version:
swift-driver version: 1.26.21 Apple Swift version 5.5.2 (swiftlang-1300.0.47.5 clang-1300.0.29.30)
Target: x86_64-apple-macosx12.0
Indeed, this is a current limitation of the underlying ICU library (for long-standing backwards-compatibility reasons); from the udat.h docs:
UDAT_FRACTIONAL_SECOND_FIELD
FieldPosition and UFieldPosition selector for 'S' field alignment, corresponding to the UCAL_MILLISECOND field.
Note: Time formats that use 'S' can display a maximum of three significant digits for fractional seconds, corresponding to millisecond resolution and a fractional seconds sub-pattern of SSS. If the sub-pattern is S or SS, the fractional seconds value will be truncated (not rounded) to the number of display places specified. If the fractional seconds sub-pattern is longer than SSS, the additional display places will be filled with zeros.
If you continue to use DateFormatter to parse fixed-format date strings, make sure to pin the locale to en_US_POSIX. See QA1480 NSDateFormatter and Internet Dates for an explanation as to why this is important.
Are there any updates to this? I'm having the same issue where my Swift.Date ISO8601 round-trip coding is not lossless.
I'm observing the millisecond rounding.
Are there any other existing solutions for ISO8601 encoding/decoding that are lossless with Swift.Date?