How to convert time String into NSDate?

2019-07-08 09:14发布

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.

标签: ios swift nsdate
3条回答
手持菜刀,她持情操
2楼-- · 2019-07-08 09:26

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
查看更多
该账号已被封号
3楼-- · 2019-07-08 09:37

There are three completely different questions here:

  1. 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.

  2. 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.

  3. 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.

查看更多
ら.Afraid
4楼-- · 2019-07-08 09:42

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.

查看更多
登录 后发表回答