NSDateFormatter parses two-digit year as 2046 inst

2019-03-06 20:15发布

I have a scenario where I'm getting a date string as "46-05-24" (yy-mm-dd), and I need to re-format the date as "1946-05-24". The NSDateFormatter interprets the string as "2046-05-24".

I'm using this code:

    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "yy-mm-dd"
    let gmt : NSTimeZone = NSTimeZone(abbreviation: "GMT")!
    dateFormatter.timeZone = gmt
    let dateFromString = dateFormatter.dateFromString(date as String)
    dateFormatter.dateFormat = "yyyy-mm-dd"
    if dateFromString != nil{
        let dateString = dateFormatter.stringFromDate(dateFromString!)
        print(dateString)
    }

Is there something I'm missing here?

2条回答
别忘想泡老子
2楼-- · 2019-03-06 20:41

It happens because if you're giving NSDateFormatter a two-digit year, it needs to decide what century that year is in. It does this using its twoDigitStartDate property, which sets the earliest date that a two-digit year can represent. It has a default value of December 31, 1949. A date in 46 falls on the low side of 50 so it gets treated as 2046.

You can change the value of twoDigitStartDate to adjust the results. For example, you could set it to a date exactly 100 years in the past. That would mean that any two-digit year would be interpreted as the most recent year with those two digits:

let oneCenturyAgo = NSCalendar.currentCalendar().dateByAddingUnit(NSCalendarUnit.Year, value: -100, toDate: NSDate(), options: NSCalendarOptions(rawValue:0))
dateFormatter.twoDigitStartDate = oneCenturyAgo

Of course if you get someone whose date is over 100 years ago, there's no good way for your code to know which year is appropriate. If the year is "10", was that person born in 1910 or 2010? You have no way of knowing, and all your code can do is make the best guess.

查看更多
别忘想泡老子
3楼-- · 2019-03-06 20:42

The cause of your problem is that your data omits some relevant information: the century. Using only the last two digits you as the dev have to decide which century the dates are in. If all of them are in the 20th century (1900 - 1999) you can use the following approach:

You could simply prepend 19 before the string to parse. Assuming date is the string that you want to parse you can use

let dateFromString = dateFormatter.dateFromString("19" + (date as String))

instead of your

let dateFromString = dateFormatter.dateFromString(date as String)

If the dates you are going to handle are in the 20th and the 21st century you are going to have a bad time because what year is 05 supposed to reflect? 1905? 2005? 2105?

查看更多
登录 后发表回答