【问题标题】:Can't form Range with upperBound < lowerBound不能用 upperBound < lowerBound 形成 Range
【发布时间】:2019-07-13 17:36:15
【问题描述】:

我正在尝试从如下所示的服务器响应中获取日期:

"dateStart": "2019-08-21T14:54:03.285108Z",

"dateEnd": "2019-09-20T06:15:03.285108Z"

由于我只需要日期和月份,所以结果将是:“08-21”和“09-20”

我确实尝试过滤结果,但我遇到了崩溃:

线程 1:致命错误:无法使用 upperBound 形成 Range

这是我的代码:

    let startTime = dealStatus["dateStart"] as? String
    let startFirst = startTime!.index(startTime!.startIndex, offsetBy: 5)
    let endFirst = startTime!.index(startTime!.endIndex, offsetBy: -17)
    let startTimeString = startTime![startFirst..<endFirst] // Getting crash here

    let endTime = dealStatus["dateEnd"] as? String
    let startSecond = endTime!.index(endTime!.startIndex, offsetBy: 5)
    let endSecond = endTime!.index(endTime!.endIndex, offsetBy: -17)
    let endTimeString = endTime![startSecond..<endSecond]

    let startReplaced = startTimeString.replacingOccurrences(of: "-", with: ".")
    let endReplaced = endTimeString.replacingOccurrences(of: "-", with: ".")
    let startEndDates = "(" + String(startReplaced) + " - " + String(endReplaced) + ")"
    //
    let orderTitle = ordersResponseArray[indexPath.row]
    let catTitle = orderTitle["title"] as? String
     cell.titleAndDatesLabel.text = catTitle! + " " + startEndDates

任何帮助将不胜感激!

【问题讨论】:

  • 你能显示dealStatus的类型吗? startFirstendFirst 是什么?我可以看到您正在使用索引做一些事情,但是这里的数据是什么?
  • 哦...我现在明白了。你的“日期”只是像“08-21”和“09-20”这样的字符串......你能解释一下你在这里实际上想要做什么吗?我觉得使用 Dates 有更好的方法。使用 Date 对象通常要好得多。并且尝试删除过时的字符串通常不是一个好主意。
  • 您也可以print(startFirst)print(endFirst) 告诉我们输出结果吗?
  • 显然startFirst 的值不是您期望的字符串,因此您的硬编码范围偏移会给出错误的结果。使用调试器查看startFirst 的实际值是多少。在尝试从字符串中提取硬编码范围之前,添加代码以检查字符串的长度。在处理从服务器获取的数据时,始终进行防御性编码。你并不总是得到你所期望的。
  • 您应该将日期字符串(UTC 时间)解析为日期对象,并从中获取本地时间日、月和年(它们可能与 UTC 时间字符串中的不同)。

标签: ios swift xcode


【解决方案1】:

您应该首先使用 DateFormatter 或 ISO8601DateFormatter 将您的日期字符串(UTC 时间)解析为日期对象,并从结果日期中获取月份和日期表示:

extension Formatter {
    static let monthDay: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "en_US_POSIX")
        dateFormatter.dateFormat = "MM.dd"
        return dateFormatter
    }()
}

extension Formatter {
    static let iso8601: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar(identifier: .iso8601)
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
        return formatter
    }()
}

游乐场测试:

let dealStatus: [String: Any] = ["dateStart": "2019-08-21T14:54:03.285108Z",
                                 "dateEnd"  : "2019-09-20T06:15:03.285108Z"]

if let dateStart = dealStatus["dateStart"] as? String,
    let dateEnd = dealStatus["dateEnd"] as? String,
    let start = Formatter.iso8601.date(from: dateStart),
    let end = Formatter.iso8601.date(from: dateEnd) { // ,
//  let catTitle = ordersResponseArray[indexPath.row]["title"] as? String {

    let startTime = Formatter.monthDay.string(from: start)
    let endTime = Formatter.monthDay.string(from: end)
    let startEndDates = "(" + startTime + " - " + endTime + ")"
    print(startEndDates)  // "(08.21 - 09.20)"
    //    cell.titleAndDatesLabel.text = catTitle + " " + startEndDates
}

【讨论】:

    猜你喜欢
    • 2017-11-26
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多