skip to Main Content

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


  1. Chosen as BEST ANSWER

    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.


  2. The primary cause of your issue is the incorrect use of YYYY in the dateFormat. You need to be using yyyy 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search