NSDateFormatter fails parsing three letter abbrevi

2019-09-08 09:00发布

问题:

I have a number of German dates in the format of "10.Feb.2016", i.e. 2 digits for the day, 3 letters for the month, 4 digits for the year.

I tried to use the date format dd.MMM.yyyy, but that fails for 3 German months:

  • 10.Mär.2016
  • 10.Jun.2016
  • 10.Jul.2016

That's because that's according to the docs, MMM actually stands for "date abbreviation", which does to guarantee or imply exactly three letters.

How can I parse a date with exactly three letters for the month that will work in any language? Is this even possible with NSDateFormatter?

The code below illustrates the problem. It prints:

OK 10.Jan.2016
OK 10.Feb.2016
FAILED parsing: 10.Mär.2016
OK 10.Apr.2016
OK 10.Mai.2016
FAILED parsing: 10.Jun.2016
FAILED parsing: 10.Jul.2016
OK 10.Aug.2016
OK 10.Sep.2016
OK 10.Okt.2016
OK 10.Nov.2016
OK 10.Dez.2016

Here's the code:

let dateFormatter = NSDateFormatter()
dateFormatter.timeZone   = NSTimeZone(abbreviation: "UTC")
dateFormatter.dateFormat = "dd.MMM.yyyy"
dateFormatter.locale     = NSLocale(localeIdentifier: "de_DE")

let input = [
    "10.Jan.2016",
    "10.Feb.2016",
    "10.Mär.2016",
    "10.Apr.2016",
    "10.Mai.2016",
    "10.Jun.2016",
    "10.Jul.2016",
    "10.Aug.2016",
    "10.Sep.2016",
    "10.Okt.2016",
    "10.Nov.2016",
    "10.Dez.2016",
]

for test in input
{
    if let date = dateFormatter.dateFromString(test)
    {
        print("OK \(test)")
    }
    else
    {
        print("FAILED parsing: \(test)")
    }
}

回答1:

Strangely when I tried your code, only "Mai" worked. All others failed.

However after taking a look at that documentation I tried this change:

dateFormatter.dateFormat = "dd.LLL.yyyy"

All of those sample dates worked ("OK" for all). LLL is the "stand-alone" month, which is described as follows:

The most important distinction to make between format and stand-alone forms is a grammatical distinction, for languages that require it. For example, many languages require that a month name without an associated day number be in the basic nominative form, while a month name with an associated day number should be in a different grammatical form: genitive, partitive, etc. Another common type of distinction between format and stand-alone involves capitalization...

I don't know enough about German to say if that should apply, but obviously NSDateFormatter thinks that it does.