如何将时间string转换成NSDate?

如何将时间string(24小时格式)转换为NSDate进行比较?

我得到无和错NSDate在这里:

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)") 

然后我得到

 A: Optional(1999-12-31 20:46:00 +0000) B: nil 

当我想要得到

 A: 5:46 AM B: 00:30 AM 

要么

 A: 05:46 B: 24:30 

只要我可以比较两个小时,哪个NSDate格式无关紧要。

在date中添加NSTimeZone

  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)") 

输出是:

 Printing description of outputA: 2000-01-01 05:46:00 +0000 Printing description of outputB: 2000-01-01 00:30:00 +0000 

这里有三个完全不同的问题:

  1. 为什么第一次约会看起来不对?

    第一次约会的时间是20:46 ,因为当地时区5:46am等于20:46 GMT (这就是+ +0000意思,GMT + 0)。 所以不要担心它看起来不一样。 简单的事实是,当地时区上午5:46是GMT + 0时20分46秒。

    人们经常推荐指定格式化程序的时timeZone到GMT / UTC。 在我看来,这是一个根本上有缺陷的方法。 这是有效的,但是它暗示了对潜在问题的误解,即NSDate对象没有固有的时区概念。 如果您想在当前时区显示时间,则始终使用格式化程序。 我假设,当你说5:46时,你的意思是上午5:46,而用户实际上是在哪里,而不是伦敦的5:46米。

    显然,如果你说5:46,你的意思是5:46 GMT(即在伦敦),那么很好,把时区设定为GMT。 你会用RFC 3339或ISO 8601等互联网date格式做很多事情,为了一致性,我们有意识地把所有事情都改成了GMT。 但是,如果情况并非如此,我认为最好让格式化程序使用默认的timeZone (当前时区),只要知道NSLog / print将总是以GMT显示时间,并知道当你想显示时间该应用程序,始终使用格式化程序正确格式化为您的本地时区。

  2. 为什么是第二次约会?

    这个有点神秘。 您的格式化程序是错误的(您应该使用dateFormattimeStyle / dateStyle ,但不是两个),但我不认为这是问题。 24:30的使用对于美国人来说有点好奇(我们通常会用到00:30 ),但我想这在英国,中国,日本和香港等国家并不是闻所未闻的。 k:mm ,所以我本以为会接受24:30 。 尽pipe如此, k:mm格式器string对我来说工作得很好。

    底线我不能重现你描述的nil行为。 也许你可以告诉我们你正在使用什么语言环境,只使用dateFormat ,而不是timeStyle

  3. 为什么输出时间格式不正确?

    如果在将原始stringparsing为NSDate对象的情况下,如果要以某种预定格式创build新的输出string,则可以使用另一个格式化程序将该NSDate转换回所需格式的string。

     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)") 

    在我的电脑上,输出:

    dateA:可选(2000-01-01 10:46:00 +0000)dateB:可选(2000-01-01 05:30:00 +0000)

    stringA:5:46 AM stringB:12:30 AM

    date是那些时间被正确地parsing成NSDate对象(输出他们的价值格林尼治标准时间,+ +0000 ),然后重新转换为输出string,无论您提供的任何风格/格式。

显然,这假定你用dateB nil解决这个问题。 请提供有关您的configuration的更多信息和/或向我们提供一个MCVE 。 但是我不能重现你描述的行为。

你可以尝试下面的代码来解决你的问题。

 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)") 

注意:如果你使用24小时时间格式,那么你不需要“24:30”,NSDate对象永远不会给你时间。 它会一直返回date也如果你将使用我在上面的代码中提到的格式。