2

I'm trying to fetch dates from a server response that look like this:

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

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

As I need only from the date only the day and the month, so the result would be: "08-21" and "09-20"

I did try to filter the resutls, but I'm getting crash:

Thread 1: Fatal error: Can't form Range with upperBound < lowerBound

here is my code:

    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

Any help would be extremely appreciated!

Community
  • 1
  • 1
Jessica Kimble
  • 493
  • 2
  • 7
  • 17
  • Can you show the type of `dealStatus`? And what is `startFirst` and `endFirst`? I can see that you’re doing something with indexes but what is the data here? – Fogmeister Jul 13 '19 at 17:39
  • 1
    Oh... I see now. Your “dates” are just strings like “08-21” and “09-20”... can you explain what you’re actually trying to do here? I feel like there is a much better approach using Dates. It’s generally much better to work with Date objects. And trying to cut bits out of date strings is generally not a good idea. – Fogmeister Jul 13 '19 at 17:42
  • 1
    Could you also `print(startFirst)` and `print(endFirst)` and let us know the output. – Fogmeister Jul 13 '19 at 17:43
  • Clearly the value of `startFirst` isn't the string you expected so your hardcoded range offsets are giving the wrong results. Use the debugger and see what the actual value of `startFirst` is. Add code to check the length of the string before attempting to extract hardcoded ranges from the string. Always code defensively when working with data you obtain from a server. You don't always get what you expect. – rmaddy Jul 13 '19 at 17:48
  • 1
    you should parse your date strings (UTC time) into date objects and get the local time day, month and year from it (they might not be the same as it is in UTC time string). – Leo Dabus Jul 13 '19 at 18:00

1 Answers1

1

You should first parse your date strings, which are UTC time, into date objects using DateFormatter or ISO8601DateFormatter and get the month and day representation from the resulting dates:

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
    }()
}

Playground testing:

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
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571