Swift 和 iso8601 尝试解析 "HH:mm:ss"

标签 swift

我们使用 Decodable,并且有一个时间:日期字段,但来自服务器的时间仅采用“HH:mm:ss”格式。另一个带有 DateInRegion 的日期解析器。

但是这个字段崩溃了应用程序 我尝试在解码器中执行某些操作,但看不到任何属性(.count) 我现在不知道需要做什么

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom({ decoder -> Date in
  do {
    let value = try decoder.singleValueContainer()
    let string = try value.decode(String.self)
    if string.conut == 8 {
        if let date = DateInRegion(
            string: string,
            format: .iso8601(options: .withTime),
            fromRegion: Region.Local()
            ) {
            return date.absoluteDate
        } else {
            throw DecodingError.nil
        }
    } else if let date = DateInRegion(
      string: string,
      format: .iso8601(options: .withInternetDateTime),
      fromRegion: Region.Local()
      ) {
      return date.absoluteDate
    } else {
      throw DecodingError.nil
    }
  } catch let error {

最佳答案

不确定您想要实现什么,但您似乎想在单个 JSON 解码器中处理多种日期格式。

假设响应结构是可解码:

struct Response: Decodable {
  var time: Date
  var time2: Date
}

您可以配置解码器来处理您想要的所有日期格式:

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
  // Extract string date from the container
  let container = try decoder.singleValueContainer()
  let stringDate = try container.decode(String.self)

  // Trying to parse the "HH:mm:ss" format
  let dateFormatter = DateFormatter()
  dateFormatter.dateFormat = "HH:mm:ss"
  if let date = dateFormatter.date(from: stringDate) {
    return date // successfully parsed "HH:mm:ss" format
  }

  // Trying to parse the iso8601 format
  if let date = ISO8601DateFormatter().date(from: stringDate) {
    return date // successfully parsed iso8601 format.
  }

  // Unknown date format, throw an error.
  let context = DecodingError.Context(codingPath: [], debugDescription: "Unable to parse a date from '\(stringDate)'")
  throw DecodingError.dataCorrupted(context)
})

注意:这是一个示例代码,并没有非常优化(DateFormatter每次要解析日期时都会初始化,使用暴力解析来确定是否是日期是否采用“HH:mm:ss”格式,...)。

我认为,优化这一点的最佳方法是使用多个解码器,每个解码器都配置为特定的日期格式,并在需要时使用正确的解码器。例如,如果您尝试从 API 解析 JSON,您应该能够确定是否需要解析 iso8601 格式或其他格式,并相应地使用正确的解码器。

这是解码器在 Playground 上工作的示例:

let json = """
{"time": "11:05:45", "time2": "2018-09-28T16:02:55+00:00"}
"""

let response = try! decoder.decode(Response.self, from: json.data(using: .utf8)!)
response.time // Jan 1, 2000 at 11:05 AM
response.time2 // Sep 28, 2018 at 6:02 PM

关于Swift 和 iso8601 尝试解析 "HH:mm:ss",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52554741/

相关文章:

ios - 当我的应用程序在 fg 上时,我的应用程序如何发送推送通知?

swift - 如何防止 boolean 值在 if 语句中被覆盖?

ios - 看起来 Apple 在 UIActivityViewController 中错误地转换了字符串

swift - 如何禁用 macOS Catalyst 应用程序中的 "Show Tab Bar"选项

ios - CallKit 不会阻止数组中的数字

ios - 如何捆绑 Realm 文件

ios - 使用 Swift 的 UILabel 中的 NSAttributedString 单击事件

ios - 从 Firebase 数据库读取数据时出现问题

ios - 在 SwiftUI 中更改 ProgressView 的大小(高度)

ios - Swift 框架伞头 - 在框架模块内包含非模块化头