如何将时间字符串转换成 NSDate?

How to convert time String into NSDate?

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

我在这里得到了 nil 和错误的 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 格式并不重要。

在日期格式中添加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:46am 在您当地的时区 20:46 GMT+0.

    人们经常建议将格式化程序的 timeZone 指定为 GMT/UTC。在我看来,这是一种根本上有缺陷的方法。这行得通,但它暗示了对根本问题的误解,即 NSDate 对象没有固有的概念时区。如果你想显示当前时区的时间,你总是使用格式化程序。我假设当你说 5:46am 时,你的意思是 5:46am 用户实际所在的位置,而不是 5:46m 在伦敦。

    显然,如果当您说 5:46 时,您确实指的是 5:46 GMT(即在伦敦),那么可以,将时区设置为 GMT。您会经常使用 RFC 3339 或 ISO 8601 等 Internet 日期格式,为了保持一致性,我们有意识地将所有内容更改为 GMT。但如果情况并非如此,我认为最好让格式化程序使用默认的 timeZone (您当前的时区)并且只需要注意 NSLog/print 将始终显示时间GMT 并且知道当您想在应用程序中显示时间时,请始终使用格式化程序将其正确格式化为您当地的时区。

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

    这个有点神秘。您的格式化程序错误(您应该使用 dateFormattimeStyle/dateStyle,但不能同时使用两者),但我认为这不是问题所在。 24:30 的使用对美国人来说有点奇怪(我们通常使用 00:30),但我想这在英国、中国、日本和香港等地并非闻所未闻。加上你正在使用 k:mm,所以我本以为它会接受 24:30。不过,k:mm 格式化程序字符串对我来说效果很好。

    底线我无法重现您描述的 nil 行为。或许您可以告诉我们您正在使用的语言环境并仅使用 dateFormat,而不是 timeStyle.

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

    如果在将原始字符串解析为 NSDate 个对象后,如果您想以某种预定格式创建新的输出字符串,那么您需要 使用另一个格式化程序 用于将 NSDate 转换回所需格式的字符串。

    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: 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

    日期是那些时间被正确解析为 NSDate 对象(以 GMT 格式输出它们的值,+0000),然后根据您提供的 style/format 重新转换为输出字符串。

显然,这假设您解决了 dateBnil 的问题。请提供有关您的配置的更多信息 and/or 向我们提供 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 对象永远不会只给您时间。如果您将使用我在上面代码中提到的格式,它也将始终 return 日期。