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:
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(Calendar.current.component(.nanosecond, from: date))
The output is:
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)
I think DateFormatter is parsing with ICU, which may only support millisecond precision.
__cficu_ucal_setMillis in CFDateFormatter.c)
Indeed, this is a current limitation of the underlying ICU library (for long-standing backwards-compatibility reasons); from the
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.
What others have said but also…
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.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
It seems I should not use DateFormatter in this case. I'll parse a date with a regular expression.