fisher fisher - 2 years ago 78
Swift Question

Can NSDateformatter be used for reading swedish months

I am trying to parse a list of dates. The dates look like this: "01MAY16, 01JUN16, 01AUG16" and so on. Up until now the dates have all been in english and I have successfully used the NSDateFormatter like this:

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "ddMMMyy"
dateFormatter.locale = NSLocale(localeIdentifier: "en_US")

let date = dateFormatter.dateFromString("01MAY16")

I have now stumbled upon an issue. The dates I parse have a tendency to be displayed with swedish locale like this: "01MAJ16, 01JUN16, 01OKT16".
I was hoping this could be parsed by setting the locale in the dateformatter to swedish like this:

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "ddMMMyy"
dateFormatter.locale = NSLocale(localeIdentifier: "sv_SE")

let date = dateFormatter.dateFromString("01MAJ16")

This works fine when the date is 'MAJ', but only because that month is a 3-letter month. If I try the following the date returned is nil:

let date = dateFormatter.dateFromString("01JUN16")

It returns nil because the format it is looking for is apparently 'juni'. So the format MMM does not imply 3-letters.

So to my question. What is the easiest way to solve this? Is there a trick I can use or do I have to create my own formatter?


I learned a lot of new things from you, thank you.
Setting the shortMonthSymbols manually is a good solution, but in my case I would have to do that for both norwegian, swedish and danish locale. I came up with a solution that overrides the dateFromString() method of the NSDateFormatter. Please tell me if I have done something very stupid.
This formatter is used when I know that all the dates I parse (any locale) always uses 3-letter month:

class CustomDateFormatter : NSDateFormatter {

override func dateFromString(string: String) -> NSDate? {

guard let date = super.dateFromString(string) else {

//I only override the dateFormatter if no date is found and the dateFormat is set to exactly 3 M's (i.e ddMMMyy)
let charactersInDateFormat = self.dateFormat.characters

let mChars = charactersInDateFormat.filter { $0 == "M" }

guard mChars.count == 3 else {

return nil

var modifiedDateString = string.lowercaseString

for monthLocale in self.shortMonthSymbols {

let index = monthLocale.startIndex.advancedBy(3)

let threeLetterMonthString = monthLocale.substringToIndex(index).lowercaseString

if modifiedDateString.containsString(threeLetterMonthString) {

modifiedDateString = modifiedDateString.stringByReplacingOccurrencesOfString(threeLetterMonthString, withString: monthLocale)


return super.dateFromString(modifiedDateString)

return date


Answer Source

The other answers are right. This is not a standard unicode format so changing locale won't help you. However, you can set month names explicitly!

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "ddMMMyy"
dateFormatter.shortMonthSymbols = ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"];

let date = dateFormatter.dateFromString("01JUN16")
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download