Hand-tooled literals do seem to have inconsistent results. I think I would recommend against them if one is in a hurry.
FB13700896
For the record, the code I'd actually recommend for what I'm doing is:
let dateString = "2024-03-12 03:12:10" //(DANGER. No time zone is a questionable choice.)
let isoDateFormat:Date.ISO8601FormatStyle = .iso8601.dateTimeSeparator(.space).year().month().day().time(includingFractionalSeconds: false)
let date = try isoDateFormat.parse(dateString)
print(isoDateFormat2.format(date))
Code that's wonky:
func testVerbatimFormatStyle() throws {
let dateString = "2024-03-12"
var dashString:Date.FormatString { "\(year: .defaultDigits)-\(month: .twoDigits)-\(day: .twoDigits)" }
let verbatimFormat:Date.VerbatimFormatStyle = .init(format: dashString, timeZone: TimeZone.gmt, calendar: Calendar.current)
let verbatimDate = try verbatimFormat.parseStrategy.parse(dateString)
let stringFromVDate = verbatimFormat.format(verbatimDate)
print(verbatimFormat.parseStrategy.format) //SIDENOTE: other FormatStyles have myFormat.parse(String)
print("date:", verbatimDate, "string:", stringFromVDate)
var dashString2:Date.FormatString { "'y-MM-dd'" }
//Works with dashString2
let strategy = Date.ParseStrategy(format: dashString2, timeZone: .gmt)
//strategy.format == "\'\'y-MM-dd\'\'"
let date = try Date(dateString, strategy: strategy)
print("newDate:", date)
//newDate 2024-03-12 00:00:00 +0000
let formatString = strategy.format //returns the format string.
print(formatString)
let date2 = try strategy.parse(dateString)
//Both pass.
XCTAssertEqual(date, date2)
XCTAssertEqual(date, verbatimDate)
//Fails with dashString2
let verbatimFormat2:Date.VerbatimFormatStyle = .init(format: dashString2, timeZone: TimeZone.gmt, calendar: Calendar.current)
//verbatimFormat2.formatPattern == "\'\'y-MM-dd\'\'"
let verbatimDate2 = try verbatimFormat2.parseStrategy.parse(dateString) // <--CAUGHT ERROR HERE.
let stringFromVDate2 = verbatimFormat2.format(verbatimDate2)
print(verbatimFormat2.parseStrategy.format)
print("date:", verbatimDate2, "string:", stringFromVDate2)
XCTAssertEqual(verbatimDate, verbatimDate2) //Never gets here.
}
//MARK: Playground Code
// Doesn’t even work in ParseStrategy
import UIKit
let dateString = "2024-03-12"
var dashString:Date.FormatString { "\(year: .defaultDigits)-\(month: .twoDigits)-\(day: .twoDigits)" }
let verbatimFormat:Date.VerbatimFormatStyle = .init(format: dashString, timeZone: TimeZone.gmt, calendar: Calendar.current)
let verbatimDate = try verbatimFormat.parseStrategy.parse(dateString)
let stringFromVDate = verbatimFormat.format(verbatimDate)
print(verbatimFormat.parseStrategy.format) //Sidenote:other FormatStyles have myFormat.parse(String)
print("date:", verbatimDate, "string:", stringFromVDate)
var dashString2:Date.FormatString { "'y-MM-dd'" }
let strategy = Date.ParseStrategy(format: dashString2, timeZone: .gmt)
let date = try Date(dateString, strategy: strategy) //<--error here in playground.
//strategy.formatPattern == "'''y-MM-dd'''"
print("newDate:", date)
//newDate 2024-03-12 00:00:00 +0000
let formatString = strategy.format //returns the format string.
print(formatString)
let date2 = try strategy.parse(dateString)
print(date == date2)
print(date == verbatimDate)
let verbatimFormat2:Date.VerbatimFormatStyle = .init(format: dashString2, timeZone: TimeZone.gmt, calendar: Calendar.current)
//verbatimFormat2.formatPattern == "'''y-MM-dd'''"
let verbatimDate2 = try verbatimFormat2.parseStrategy.parse(dateString)
let stringFromVDate2 = verbatimFormat2.format(verbatimDate2)
print(verbatimFormat2.parseStrategy.format)
print("date:", verbatimDate2, "string:", stringFromVDate2)
ETA: Note a successful format round trip for a ParseStrategy looks like
var dashString3:Date.FormatString {
Date.FormatString(stringLiteral: "'\(verbatimFormat.parseStrategy.format)'")
}
let strategy3 = Date.ParseStrategy(format: dashString3, timeZone: .gmt)
let date3 = try Date(dateString, strategy: strategy3)
(Still doesn't work for a VerbatimFormatStyle parse.)