Hey there,
I was using the new ISO8601FormatStyle and using the includingFractionalSeconds option for it. But when decoding and encoding an iso8601 string, I do get rounding errors in the millisecond part.
I have setup a simple unit test:
import Testing
import UIKit
struct DateFormatterTests {
@Test func testDateEncodingDecoding() async throws {
let originalIsoString = "2024-10-05T17:08:34.650Z"
let iso8601DateFormatter = ISO8601DateFormatter()
iso8601DateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let testDate = iso8601DateFormatter.date(from: originalIsoString)!
let oldFormatterString = iso8601DateFormatter.string(from: testDate)
#expect(oldFormatterString == originalIsoString)
let isoDateFormat: Date.ISO8601FormatStyle = .iso8601
.year()
.month()
.day()
.timeZone(separator: .omitted)
.time(includingFractionalSeconds: true)
.timeSeparator(.colon)
let date = try isoDateFormat.parse(originalIsoString)
let newFormatterString = isoDateFormat.format(date)
#expect(newFormatterString == originalIsoString)
}
}
This gives the following output:
✘ Test testDateEncodingDecoding() recorded an issue at DateFormatterTests.swift:35:9: Expectation failed: (newFormatterString → "2024-10-05T17:08:34.649Z") == (originalIsoString → "2024-10-05T17:08:34.650Z")
It has a rounding error in the new ISO8601FormatStyle of 1 ms.
Am I doing something fundamentally wrong here or is there something else at play? I probably has something to with date Date uses a floating type internally I guess?
EDIT:
I am using XCode Version 16.0 (16A242d)
Testing on my iPhone 12 Pro using iOS 18.0
I think it is still compiled with Swift 5 (Swift Language Version is set to Swift 5 as far as I can tell).