Getting Wrong Date from dateFormat

2019-02-28 15:44发布

问题:

For date Input "00/02/02"
formating Style is yy/MM/dd
I am getting correct output like 02/01/2000

But issue is when trying with "00/01/01" getting output like this '01/01/12100'

But I don't know why this year coming like 12100

My code is

let str = "00/01/01"

let inputFormatter = DateFormatter()
inputFormatter.dateFormat = "yy/MM/dd"
if let showDate = inputFormatter.date(from: str) {
   inputFormatter.dateFormat = "dd/MM/yyyy"
   let resultString = inputFormatter.string(from: showDate)
   print(resultString)
 }

year input type always as yy format.

回答1:

I managed to reproduce this bug by setting the timezone of the formatter, before getting the date from it, to your local timezone:

inputFormatter.timeZone = TimeZone(identifier: "Asia/Kolkata")
//Or
inputFormatter.timeZone = TimeZone(identifier: "Asia/Calcutta") 

They both lead to 01/01/12100.

Actually, using a date format of yy/MM/dd hh:mm:ss, all dates starting from 00/01/01 00:00:00 to 00/01/01 05:29:59 give a year component of 12100. This is due to the time zone of Kolkata being offset by +05H30 from GMT. This is a bug.

Setting the timezone to UTC yields the desired output:

inputFormatter.timeZone = TimeZone(identifier: "UTC")  //01/01/2000

This bug occurs with other timezones too:

inputFormatter.timeZone = TimeZone(identifier: "Africa/Addis_Ababa")
inputFormatter.timeZone = TimeZone(identifier: "Europe/Moscow")
inputFormatter.timeZone = TimeZone(identifier: "Asia/Hong_Kong")

Basically all timezones that have GMT + hh:mm



回答2:

As per the @MartinR suggestion settinginputFormatter.defaultDate to current date or Date(timeIntervalSinceReferenceDate: 0) its worked fine

let str = "00/01/01"

let inputFormatter = DateFormatter()
inputFormatter.defaultDate = Date(timeIntervalSinceReferenceDate: 0)
inputFormatter.dateFormat = "yy/MM/dd"
if let showDate = inputFormatter.date(from: str) {
  inputFormatter.dateFormat = "dd/MM/yyyy"
 let resultString = inputFormatter.string(from: showDate)
 print(resultString)
 }