Dateformatter with "dd-MMM-yyyy" for September month returning wrong date

Dateformatter with "dd-MMM-yyyy" for September month returning date as "01-Sept-2022" for new version of iOS and for old its returning as "01-Sep-2022"

Why its returning 4 character abbreviation even after requested for 3 character

Answered by DTS Engineer in 713272022

Should be worth a bug report, at least against documentation.

No.

The expected behaviour of DateFormatter (NSDateFormatter in Objective-C) is that it will render and parse dates in a way that makes sense to the user. This can change:

  • From release to release, as Apple imports new versions of CLDR

  • From region to region

  • From user to user, because users can override their region’s default settings

The only exception to this is if you set the locale to to en_US_POSIX.

So, if you’re working with fixed-format dates:

  1. Try to use ISO8601DateFormatter, which was specifically designed for that task.

  2. If that doesn’t meet your needs, use DateFormatter and pin the locale to en_US_POSIX.

This is well documented — originally in QA1480 NSDateFormatter and Internet Dates but since then it’s been rolled into the official DateFormatter docs — but the shape of the API means that folks continue to fall into this trap (r. 33988168).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Is it only for this specific data ?

Could you show the complete code for testing ?

Accepted Answer

I tested code in Xcode 13.2.1 and iOS 15.2 simulator. It works.

Effectively, when testing in Xcode 13.3 and iOS 15.4 simulator, it crashes.

I had to define dateFormatter.locale

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

to make it work.

So there is an undocumented change with Xcode 13.3 or iOS 15.4.

Should be worth a bug report, at least against documentation.

Why its returning 4 character abbreviation even after requested for 3 character

  • I could not get this error.
  • But I get a nil for formatedStartDate, as you did, which explains the crash when you unwrap later.

Should be worth a bug report, at least against documentation.

No.

The expected behaviour of DateFormatter (NSDateFormatter in Objective-C) is that it will render and parse dates in a way that makes sense to the user. This can change:

  • From release to release, as Apple imports new versions of CLDR

  • From region to region

  • From user to user, because users can override their region’s default settings

The only exception to this is if you set the locale to to en_US_POSIX.

So, if you’re working with fixed-format dates:

  1. Try to use ISO8601DateFormatter, which was specifically designed for that task.

  2. If that doesn’t meet your needs, use DateFormatter and pin the locale to en_US_POSIX.

This is well documented — originally in QA1480 NSDateFormatter and Internet Dates but since then it’s been rolled into the official DateFormatter docs — but the shape of the API means that folks continue to fall into this trap (r. 33988168).

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

But it could be useful for doc to remind it.

This is already documented pretty well, including:

The problem here is that the obvious API is a trap, and I don’t think we’ll ever eliminate that trap without changing the API.

This can change from release to release, as Apple imports new versions of CLDR

Right. It can also change from user to user. The Buddhist calendar example from QA1480 is instructive. I once took a DTS TSI from a bank in Australia where the app worked fine for all their users except for a small subset of their customers in Thailand, where all the dates were off by approximately 500 years.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Same old code is working fine on latest version of iOS 15.5 after update

While 15.5 beta may have solved this specific issue, parsing fixed-format dates without using en_US_POSIX is wrong and has always been wrong. You still need to fix your code.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Looks like Apple has fix date format issue in latest version on iOS 15.5 Same old code is working fine on latest version of iOS 15.5 after update

Dateformatter with "dd-MMM-yyyy" for September month returning wrong date
 
 
Q