I have this simple code (Xcode iOS app)
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Button(action: {
let dateToday = Date()
let dateOneYearAgo = Calendar.current.date(byAdding: .year, value: -1, to: dateToday) ?? dateToday
print("dateToday: (dateToday) - dateOneYearAgo: (dateOneYearAgo)")
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd"
let dateTodayString = dateFormatter.string(from: dateToday)
let dateOneYearAgoString = dateFormatter.string(from: dateOneYearAgo)
print("dateTodayString: (dateTodayString) - dateOneYearAgoString: (dateOneYearAgoString)")
}, label: {
Text("Test").font(.largeTitle)
})
}
.padding()
}
}
If I run it in Simulator it prints out
dateToday: 2022-12-29 17:24:37 +0000 – dateOneYearAgo: 2021-12-29 17:24:37 +0000
dateTodayString: 2022-12-29 – dateOneYearAgoString: 2022-12-29
If I run in Swift Playgrounds just the action closure like:
import Foundation
let dateToday = Date()
let dateOneYearAgo = Calendar.current.date(byAdding: .year, value: -1, to: dateToday) ?? dateToday
print("dateToday: (dateToday) - dateOneYearAgo: (dateOneYearAgo)")
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "YYYY-MM-dd"
let dateString = dateFormatter.string(from: dateToday)
let dateOneYearAgoString = dateFormatter.string(from: dateOneYearAgo)
print("dateToday: (dateString) - dateOneYearAgo: (dateOneYearAgoString)")
it gives me:
dateToday: 2022-12-29 17:27:32 +0000 – dateOneYearAgo: 2021-12-29 17:27:32 +0000
dateTodayString: 2022-12-29 – dateOneYearAgoString: 2021-12-29
I would expect that dateOneYearAgoString is always 2021-12-29.
What do I miss here?
2
Answers
As mentioned in the comments by @HangarRash the YYYY DateFormat is causing this.
Use yyyy instead of YYYY. The latter is the date formatter token for the year in the week of year calendar.
The primary cause of your issue is the incorrect use of
YYYY
in thedateFormat
. You need to be usingyyyy
for the year.YYYY
is similar but it typically gives the wrong results during the last half of the last week of the year (like now).See Date Field Symbol Table and see the difference between y and Y.
As for why the SwiftUI code in the simulator gives a different result than the Swift code in a Playground, I suspect it has to do with the default locale and/or calendar being used by the two. Either way, correctly using
yyyy
for the year will give you the correct result in both places.