Search code examples
iosswiftnsdateformatterfoundation

DateFormatter behaves different based on user time settings


I've come across a bit of peculiarity, and I'm not sure why it's happening or how to deal with it.

let formatter = DateFormatter()
formatter.dateFormat = "h:mma"
let timeString = "8:00am"
let date = formatter.date(from: timeString)!

This code works if the user has their time set to use a 12 hour clock. If they have their device set to a 24 hour clock, it crashes.

How do I make make it work independent of the user's settings?


Solution

  • You will have to change the locale to the standard POSIX locale:

    formatter.locale = Locale(identifier: "en_US_POSIX")
    

    See the technical note QA1480:

    On iOS, the user can override the default AM/PM versus 24-hour time setting (via Settings > General > Date & Time > 24-Hour Time), which causes NSDateFormatter to rewrite the format string you set, which can cause your time parsing to fail.

    Note that it's a bad practice to enforce a specific time format if you are not parsing/encoding data. If you want to show formatted time to users, a much better solutions is to use the user defined formatting:

    let formatter = DateFormatter()
    formatter.dateStyle = .none
    formatter.timeStyle = .short