Description
When CloudKit returns dates in standard ISO8601 format (e.g., 2026-03-21T03:57:40.026Z), SyncEngine fails to parse them with the error:
Cannot parse 2026-03-21T03:57:40.026Z. String should adhere to the preferred format of the locale, such as 2026-03-21 03:57:40.
Root Cause
The ISO8601.swift internal helpers use a non-standard date format:
// Current implementation (incorrect for CloudKit)
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS" // Space separator, no timezone
// On iOS 15+
.dateTimeSeparator(.space) // Also expects space instead of 'T'
But CloudKit returns standard ISO8601 with T separator and Z timezone suffix:
Suggested Fix
Update ISO8601.swift to handle the standard format:
extension DateFormatter {
fileprivate static let iso8601Fractional: DateFormatter = {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" // Standard ISO8601
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}()
}
@available(iOS 15, macOS 12, tvOS 15, watchOS 8, *)
extension Date.ISO8601FormatStyle {
fileprivate func currentTimestamp(includingFractionalSeconds: Bool) -> Self {
year().month().day()
.dateTimeSeparator(.standard) // Use 'T' separator
.time(includingFractionalSeconds: includingFractionalSeconds)
.timeZone(separator: .omitted) // Handle 'Z' suffix
}
}
Alternatively, the parser should try both formats - space-separated (for SQLite storage) and standard ISO8601 (for CloudKit).
Reproducibility
- Create a
@Table with a Date field
- Sync to CloudKit via
SyncEngine
- On a different device, attempt to sync down the record
- Date parsing fails with the above error
Environment
- sqlite-data: 1.6.0
- iOS/macOS: 17+/14+
- CloudKit: Private database
Description
When CloudKit returns dates in standard ISO8601 format (e.g.,
2026-03-21T03:57:40.026Z),SyncEnginefails to parse them with the error:Root Cause
The
ISO8601.swiftinternal helpers use a non-standard date format:But CloudKit returns standard ISO8601 with
Tseparator andZtimezone suffix:2026-03-21T03:57:40.026ZSuggested Fix
Update
ISO8601.swiftto handle the standard format:Alternatively, the parser should try both formats - space-separated (for SQLite storage) and standard ISO8601 (for CloudKit).
Reproducibility
@Tablewith aDatefieldSyncEngineEnvironment