【问题标题】:How do I format JSON Date String with Swift?如何使用 Swift 格式化 JSON 日期字符串?
【发布时间】:2026-02-10 13:50:01
【问题描述】:

我向服务器发出一个 http get 请求并返回一个带有如下日期字符串的 json 对象:

{
    name = "Place1";
    temperature = 79;
    humidity = 68;
    reported_at = "2013-07-21T19:32:00Z";
}

我想格式化reported_at 键,以便向用户显示可读的日期和时间。

这是我正在尝试的快速代码,它一直返回 nil,因为它无法格式化日期。

    var str = "2013-07-21T19:32:00Z"

    var dateFor: NSDateFormatter = NSDateFormatter()
    dateFor.dateFormat = "yyyy-MM-dd'T'HH:mm:ss:SSS"

    var yourDate: NSDate? = dateFor.dateFromString(str)

    println(yourDate)

如何使用 Swift 正确格式化此日期和时间?我想向用户显示日期和时间,以便他们知道读数的时间。

【问题讨论】:

    标签: json swift nsdateformatter


    【解决方案1】:

    使用以下字符串格式将服务器字符串转换为日期

    dateFor.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
    

    【讨论】:

    • 请勿引用Z。这将给出错误的结果。
    • @rmaddy 刚刚尝试过,不引用“Z”是错误的
    • @zellb 我可以向你保证,引用Z 会给出错误的结果。如果您认为在不引用 Z 时得到了错误的结果,那么您就是在做其他错误的事情或误解了结果。
    • 2015-02-27T11:24:00Z 的日期是格林威治标准时间上午 11:24(这就是 Z 在日期字符串中的含义)。您必须居住在 GMT+1 时区。正确的?如果您不引用 Z,则日期字符串会以 GMT 时间正确解释。如果您确实引用了Z,则日期字符串在当地时间的解释不正确。
    • "yyyy-MM-dd'T'HH:mm:ssX" 应该是正确的日期格式
    【解决方案2】:

    现在(2017 年 9 月)在 Swift 4 中有更智能的方法来解码 ISO8601:

    • ISO8601DateFormatter

      let str = "2013-07-21T19:32:00Z"
      let formatter = ISO8601DateFormatter()
      let yourDate = formatter.date(from: str)
      
    • JSONDecoder

      struct Place : Decodable {
      
          let name : String
          let temperature : Int
          let humidity : Int
          let reportedAt : Date
      
      }
      
      let json = """
      {"name" : "Place1", "temperature" : 79, "humidity" : 68, "reported_at" : "2013-07-21T19:32:00Z"}
      """
      let data = Data(json.utf8)
      
      let decoder =  JSONDecoder()
      decoder.dateDecodingStrategy = .iso8601
      decoder.keyDecodingStrategy = .convertFromSnakeCase
      let place = try! decoder.decode(Place.self, from: data)
      

    【讨论】:

    • 在 ios 10 及更高版本中可用
    • 很好的答案。谢谢
    【解决方案3】:

    如果您使用SwiftDate(您可能应该!),只需使用:

    序列化:

    let date:NSDate = ....
    let dateInRegion = DateInRegion( absoluteTime: date )
    let serializedString:String = dateInRegin.toString( .ISO8601Format( .Full ))!
    

    反序列化:

    let serializedDate:String = "2016-03-01T22:10:55.200Z"
    let date:NSDate? = serializedDate.toDateFromISO8601()
    

    【讨论】:

    【解决方案4】:

    这是我在Swift4 中使用extension 的答案。

    extension String {
      func toDate(dateFormat: String) -> Date? {
    
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = dateFormat
    
        let date: Date? = dateFormatter.date(from: self)
        return date
    }
    

    简单用法

    let str = "2013-07-21T19:32:00Z";
    let dateStr = str.toDate(dateFormat: "yyyy-MM-dd'T'HH:mm:ssZ")
    

    另外,从这里检查您想要的日期格式。 ISO 8601

    【讨论】:

    • 在 Swift 4 中我更喜欢 ISO8601DateFormatter 或直接使用 JSONDecoder 解码 JSON
    • @vad 是的,使用JSONDecoder 会更好。但是,ISO8601DateFormatter,它不支持毫秒。 *.com/questions/41847672/…
    • 问题中没有毫秒,macOS 10.13 / iOS 11 支持毫秒。
    【解决方案5】:

    对于将JSON 字符串转换为Swift 3.0 中的日期和时间,请使用以下代码:-

        let timeinterval : TimeInterval = (checkInTime as! NSString).doubleValue
        let dateFromServer = NSDate(timeIntervalSince1970:timeinterval)
        print(dateFromServer)
        let dateFormater : DateFormatter = DateFormatter()
        //dateFormater.dateFormat = "dd-MMM-yyyy HH:mm a"  // 22-Sep-2017 14:53 PM
        dateFormater.dateFormat = "dd-MMM-yyyy hh:mm a"   // 22-Sep-2017 02:53 PM
        print(dateFormater.string(from: dateFromServer as Date))
    

    checkInTime 将是您的字符串。希望它会帮助某人

    【讨论】:

      【解决方案6】:

      在 Swift 5 中,如果您有一个不在“iso8601”中的自定义日期字符串,您可以执行以下操作(这是 vadian 答案的变体):

      struct Place : Decodable {
      
          let name : String
          let temperature : Int
          let humidity : Int
          let reportedAt : Date
      
      }
      
      let json = """
      {"name" : "Place1", "temperature" : 79, "humidity" : 68, "reported_at" : "2021-05-02 06:00"}
      """
      let data = Data(json.utf8)
      
      //FORMAT DATE
      let dateFormatter = DateFormatter()
      //Force dateFormatter to be always 24h
      dateFormatter.setLocalizedDateFormatFromTemplate("HH:mm a")
      dateFormatter.amSymbol = ""
      dateFormatter.pmSymbol = ""
      dateFormatter.locale = Locale(identifier: "en_US")
      dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
      
      let decoder =  JSONDecoder()
      decoder.dateDecodingStrategy = .formatted(dateFormatter)
      decoder.keyDecodingStrategy = .convertFromSnakeCase
      let place = try! decoder.decode(Place.self, from: data)
      

      【讨论】: