6

I am trying to use dateFormatter to convert from a string. It works fine on the simulators and works fine on my phone when set to 12 hour time, but fails to set when my phone is set to 24 hour. (It does set when the simulator is set to 24 hour).

passedTime = "10:36 pm"
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "h:mm a"
let pickerDate = dateFormatter.dateFromString(passedTime)
println(pickerDate)

Like I said, when run on the simulator or on my phone in 12 hour, it works perfect, but when the phone is sett 24 hour, it prints nil. I have read somethings about locale settings, but when I run this on my phone, the local is the same regardless of whether I am in 12 hour or 24 hour mode.

Connor Pearson
  • 63,902
  • 28
  • 145
  • 142
  • How are you getting the time from the phone? I usually just create a new NSDate object to get the current time and date. – Garret May 01 '15 at 03:18
  • 2
    You need to set the locale. See http://stackoverflow.com/questions/6613110/what-is-the-best-way-to-deal-with-the-nsdateformatter-locale-feature – Hot Licks May 01 '15 at 04:14
  • @HotLicks Might be best to give comment on answers you decide to down vote. – Beau Nouvelle May 01 '15 at 04:19
  • @BeauYoung - Is there some answer of yours you'd like me to downvote? – Hot Licks May 01 '15 at 04:20
  • 1
    @HotLicks Only if you give good reason to do so. We're here to help each other. If the answers skim and I provided are incorrect, at least let us know why. – Beau Nouvelle May 01 '15 at 04:23
  • @HotLicks Then say that. This way, the answer can be updated, and the person can inform you of the update, in which you can remove your down vote. Do I really need to explain how this works to someone who has 25k+ rep? – Beau Nouvelle May 01 '15 at 04:34
  • @BeauYoung - What are all those points for, if not to downvote? There is literally no other use for them. (I rarely ask questions, and I've found bounties to be useless anyway.) – Hot Licks May 01 '15 at 04:49
  • @Hot Licks - I saw that thread, but struggled to get the locale to make any difference. Is there a locale setting in the date formatter for Swift? I didn't see it. – David Burnham May 01 '15 at 09:55
  • It's the same date formatter. The spec shows a `locale` property for Swift. – Hot Licks May 01 '15 at 12:00
  • https://developer.apple.com/library/archive/qa/qa1480/_index.html – Raunak Sep 26 '19 at 10:01

3 Answers3

13

I had exactly the same issue... very frustrating. The solution is to set the locale of your calendar. For Swift 3 it's: yourDateFormatter.locale = Locale(identifier: "en-US")

danharsanyi
  • 416
  • 5
  • 5
  • I had similar problem, trying to parse server response in 24 hours format to a Codable model on a device in 12 hours format in this case the parsing fail, i was setting the current device locale to the dateFormatter an it fails, specifying a locale did the trick. – BuguiBu Jun 03 '19 at 08:37
1

Be sure to put in a check for 12h/24h and set up the formatter accordingly by using "H" for 24h, and "h" for 12h.

enter image description here

Table taken from a blog post on Waracle.com, where you can find the complete list.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Beau Nouvelle
  • 6,962
  • 3
  • 39
  • 54
  • 1
    @MartijnPieters Sorry, but you are nitpicking. It was clear to anyone that this was a citation, putting an image into a blockquote is not really meaningful and a proper link was given. And an example is just an example, it's nothing you "have to follow", it's not a rule, it only says "that's how you **could** do it". And please stop re-posting the same link over and over again, everyone here has already seen it after your first comment, we are not slow-witted. If you have too much time by your hands, then go around and fix all citations on SO, for me the answer was good the way it was. – Mecki Sep 14 '17 at 09:42
  • @Mecki the policy is to use a blockquote. This is now becoming useless noise. If you want to discuss policy, you can post on [Meta]. – Martijn Pieters Sep 14 '17 at 10:20
1

How about using two date formatter to parse?

var time12hrFormatter = NSDateFormatter()
time12hrFormatter.dateFormat = "h:mm a"
var time24hrFormatter = NSDateFormatter()
time24hrFormatter.dateFormat = "HH:mm"

if let pickerDate = time12hrFormatter.dateFromString(passedTime) {
    println(pickerDate)
} else if let pickerDate = time24hrFormatter.dateFromString(passedTime) {
    println(pickerDate)
} else {
    println("failed to parse '\(passedTime)'")
}
skim
  • 2,267
  • 2
  • 16
  • 17
  • I have tried something like this and it still fails (on the phone, not the simulator). The string is clearly formatted in h:mm a form, so trying to parse it in HH:mm doesn't work. What I can't explain is why h:mm a only works when the phone is in 12 hour format. – David Burnham May 01 '15 at 10:01
  • In that case I think @HotLicks already provided the answer above: _set the local of the date formatter to one that is neutral._ – skim May 04 '15 at 16:19