shim's answer was spot on, but I'd like to provide a few more clarifying details.
On December 15, 2017, Brazilian President Michel Temer signed a decree changing the start of daylight saving time (DST) to the first Sunday of November, beginning in 2018. It looks like iOS 11.2.6 is the first version of iOS to pick up this change which is why this issue wasn't seen in previous iOS versions.
The problem with the time change moving to the first Sunday in November is that the first Sunday in November can end up being (and is in the case of 2020 and 2026) November 1st. Why does this present a problem? Well it just so happens that Brazil also has their clocks "spring forward" at midnight (going from 11:59pm to 1:00am) when DST starts.
Why does a date of November 1st at midnight present a problem? Well when we ask iOS to give us a Date object based on only month/year as the user enters (e.g. 11/20), the Date object defaults to the first day of the month at midnight. This is problematic because on years where DST starts on November 1st at midnight in Brazil, that time technically never exists. So when we ask iOS to give us a Date object for 11/20, iOS tries to return 11/01/2020 @ 00:00, but it is returning nil since that time never exists.
So this issue could technically happen in any timezone that observes DST that can start on the 1st of a month at midnight. After going through some countries and checking their DST rules, I've only found Brazil to allow DST to start on the 1st of a month at midnight.
To fix this issue I effectively did the following:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/yy"
let dateFormatterWithTime = DateFormatter()
dateFormatterWithTime.dateFormat = "MM/yy HH:mm"
if let date = dateFormatter.date(from: "11/20") ??
dateFormatterWithTime.date(from: "11/20 03:00") {
print("got the date: \(date)")
} else {
print("failed getting the date")
}
03:00
is an arbitrary amount of time in the future that should safely account for DST changes from midnight.
TimeZone
on thedateFormatter
rather than just using the device settings? What time zone do you select in Date & Time settings?dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
it no longer returns nil for "11/20".seconds from GMT: 0
is not the same time zone as UTC-2…