Reputation: 2298
How can I convert time string (in 24h format) into NSDate for comparison?
I get nil and wrong NSDate here:
let a = "5:46"
let b = "24:30"
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = .ShortStyle
dateFormatter.dateFormat = "k:mm" // k = Hour in 1~24, mm = Minute
let outputA = dateFormatter.dateFromString(a)
let outputB = dateFormatter.dateFromString(b)
println("A: \(outputA) B: \(outputB)")
Then I get
A: Optional(1999-12-31 20:46:00 +0000) B: nil
when I wish to get
A: 5:46 AM B: 00:30 AM
or
A: 05:46 B: 24:30
It doesn't really matter which NSDate format as long as I can compare those two hours.
Upvotes: 2
Views: 2613
Reputation: 437432
There are three completely different questions here:
Why does the first date look wrong?
You are getting 20:46
for the first date because 5:46am
in your local time zone is equal to 20:46 GMT
(that's what the +0000
means, GMT+0). So don't worry about that it looks different. The simple truth is that 5:46am in your local timezone is 20:46 GMT+0.
People frequently recommend specifying the formatter's timeZone
to GMT/UTC. In my opinion, that's a fundamentally flawed approach. That works, but it suggests a misunderstanding of the underlying issue, that NSDate
objects do not have an inherent concept timezone. If you want to show a time in a current time zone, you always use a formatter. I'm presuming that when you say 5:46am, you mean 5:46am where the user actually is located, rather than 5:46m in London.
Clearly, if when you say 5:46, you really meant 5:46 GMT (i.e. in London), then fine, set the timezone to be GMT. You'll do that a lot with Internet date formats like RFC 3339 or ISO 8601, where we do consciously change everything to GMT for consistency's sake. But if that's not the case, I think it's better to let the formatter use the default timeZone
(your current timezone) and just be aware that NSLog
/print
will always show the time in GMT and know that when you want to show the time in the app, always use a formatter to properly format it for your local time zone.
Why is the second date nil
?
This one is a bit of a mystery. Your formatter is wrong (you should use either dateFormat
or timeStyle
/dateStyle
, but not both), but I don't think that's the problem. The use of 24:30
is a little curious to US eyes (we'd generally use 00:30
), but I guess its not unheard of in UK, China, Japan, and Hong Kong, etc. Plus you're using k:mm
, so I would have thought that it would have accepted 24:30
. The k:mm
formatter string worked fine for me, though.
Bottom line I cannot reproduce the nil
behavior you describe. Perhaps you can tell us what locale you're using and use just dateFormat
, but not timeStyle
.
Why are the output times not formatted properly?
If, having parsed the original strings to NSDate
objects, if you want to create a new output string in some predetermined format, then you'd use another formatter for converting that NSDate
back into a string in the desired format.
let a = "5:46"
let b = "24:30"
let inputFormatter = NSDateFormatter()
inputFormatter.dateFormat = "k:mm" // k = Hour in 1~24, mm = Minute
let dateA = inputFormatter.dateFromString(a)
let dateB = inputFormatter.dateFromString(b)
println("dateA: \(dateA) dateB: \(dateB)")
let outputFormatter = NSDateFormatter()
outputFormatter.timeStyle = .ShortStyle
let stringA = outputFormatter.stringFromDate(dateA!) // these only work if the date is not `nil`
let stringB = outputFormatter.stringFromDate(dateB!)
println("stringA: \(stringA) stringB: \(stringB)")
On my computer, that outputs:
dateA: Optional(2000-01-01 10:46:00 +0000) dateB: Optional(2000-01-01 05:30:00 +0000)
stringA: 5:46 AM stringB: 12:30 AM
The dates are those times are correctly parsed into NSDate
objects (which output their value in GMT, +0000
) and then reconverted to output strings per whatever style/format you provide.
Clearly, this assumes you fix the issue with dateB
being nil
. Please provide more information regarding your configuration and/or provide us a MCVE. But I cannot reproduce the behavior you describe.
Upvotes: 1
Reputation: 478
you can try the below code for the your problem.
let a = "5:46"
let b = "24:30"
let dtf = NSDateFormatter()
dtf.timeZone = NSTimeZone(name: "UTC")
dtf.dateFormat = "HH:mm"
let date : NSDate = dtf.dateFromString(a)!
let date1 : NSDate = dtf.dateFromString(b)!
println("\(date)","\(date1)")
Note: If you are using 24 hour time format then u don't need to take "24:30" and NSDate object will never give you only time. it will always return date also if you will use the format which i mentioned in above code.
Upvotes: 0
Reputation: 3984
Add NSTimeZone
in date formate.
let a = "5:46"
let b = "24:30"
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = .ShortStyle
dateFormatter.dateFormat = "k:mm" // k = Hour in 1~24, mm = Minute
let timeZone = NSTimeZone(name: "UTC")
dateFormatter.timeZone=timeZone
let outputA = dateFormatter.dateFromString(a)
let outputB = dateFormatter.dateFromString(b)
println("A: \(outputA) B: \(outputB)")
Output is :
Printing description of outputA:
2000-01-01 05:46:00 +0000
Printing description of outputB:
2000-01-01 00:30:00 +0000
Upvotes: 0