Search code examples
iosswiftnsdatensdateformatternsdatecomponents

Swift date formatter ignoring months


I wrote a date reformatter but it appears Swift's date formatter itself is ignoring the months. The documentation says this shouldn't be happening. How do I make it not ignore months?

let testDate:String = "2020-11-22-11:00"
               
print("start date: ",testDate," reformatted date: ", reformatDate(dateString: testDate))
               

func reformatDate(dateString: String) -> String? {
                   print("dateString: ",dateString)
                   let dateFormatter = DateFormatter()
                   dateFormatter.dateFormat = "yyyy-MM-DD-HH:mm"
                   dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
                   return dateFormatter.string(from: dateString)
                                
}

this prints:

start date: 2020-11-22-11:00 converted date: 22-01-2020 11:00 AM

It unreasonably turns all months to 1!


Solution

  • Your format string is incorrect. It should be:

    yyyy-MM-dd-HH:mm
    

    and

    dd-MM-yyyy h:mm a
    

    dd means day-of-month, whereas DD means day-of-year.

    Note that you should also do:

    dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    

    whenever you are using a custom date format.

    Parsing 2020-11-22-11:00 with yyyy-MM-DD-HH:mm means that you want the twenty second day of the year 2020, in the month November. That makes no sense, and DateFormatter ends up ignoring the month because apparently day-of-year is a "stronger" date component. The 22nd day of any year is the 22nd of January.

    Then, when you format the parsed date with DD-MM-yyyy h:mm a, the month component gets displayed as 01, and the day-of-year is still displayed as 22.

    Here are some useful links to learn about format specifiers, you'll just how much lowercase/uppercase matters.