【问题标题】:Split Two Dates from One String Swift从一个字符串 Swift 中拆分两个日期
【发布时间】:2023-03-03 00:32:01
【问题描述】:

我有一个按钮,当用户按下它时,它会使用事件的开始日期和结束日期将事件的日期保存到他们的日历中。

此开始日期和结束日期是从 json 响应中加载的,但两个日期都在一个字符串中接收。

我收到的响应格式如下:

{
   "events":[
      {
         "date":"5/12/2021 - 5/14/2021",
      },
      {
         "date":"6/22/2021 - 6/25/2021",
      }
       ]
}

为了正确保存到日历,我需要将开始日期和结束日期与格式如下的字符串分开:“MM/DD/YYYY - MM/DD/YYYY”,以便字符串中的第一个日期是名为 startDate 的变量,第二个日期是名为 endDate 的变量。

如果我对两个“虚拟”数组进行硬编码,我能够解析 json 响应并且按钮可以正常工作,但是一旦我收到此“MM/DD/YYYY - MM/”,如何将响应拆分为两个单独的日期变量DD/YYYY”?

【问题讨论】:

  • 实现init(from decoder : Decoder)并添加将String拆分为两个Dates的逻辑
  • 我能够解析 json 响应,但是一旦我收到这个“MM/DD/YYYY - MM/DD/YYYY”,如何拆分日期?
  • 你不能使用 DateFormatter,你有两个日期,所以你需要先将字符串分成代表 2 个日期的 2 个字符串,然后在每个字符串上使用 DateFormatter

标签: arrays swift dateformatter


【解决方案1】:

这应该适合你:

struct Response: Codable {
    let events: [Event]
}

struct Event: Codable {
    let date: String
    
    let startDate: Date
    let endDate: Date
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        date = try container.decode(String.self, forKey: .date)
        
        let splitted = date.components(separatedBy: " - ")
        
        guard let startDateString = splitted.first,
              let endDateString = splitted.last else {
            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "'date' should follow the format 'DATE1 - DATE2'"))
        }
            
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "M/dd/yyyy"
            
        guard let extractedStartDate = formatter.date(from: startDateString),
              let extractedEndDate = formatter.date(from: endDateString) else {
            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: [], debugDescription: "The provided dates are not in the correct format M/dd/yyyy"))
        }
        startDate = extractedStartDate
        endDate = extractedEndDate
    }
}

还有一个从你的 json 解析它的例子:

let json = """
{
   "events":[
      {
         "date":"5/12/2021 - 5/14/2021",
      },
      {
         "date":"6/22/2021 - 6/25/2021",
      }
       ]
}
"""

let response = try JSONDecoder().decode(Response.self, from: json.data(using: .utf8)!)
print(response.events)

【讨论】:

  • 我认为将日期属性设为可选比强制展开这么多次更有意义
  • 由于没有日期和 init(decoder) 抛出事件将毫无意义,我更喜欢通过强制展开使其崩溃
  • 将它们设为可选将留给调用代码来决定当日期为零时该怎么做,“让它崩溃”是一个真的坏习惯。
  • 最好抛出 DecodingError
  • 很好,我现在正在编辑,我猜你总能学到一些东西
猜你喜欢
  • 2020-03-07
  • 1970-01-01
  • 2018-01-06
  • 1970-01-01
  • 2014-01-16
  • 1970-01-01
  • 2011-06-14
  • 2014-08-06
  • 1970-01-01
相关资源
最近更新 更多