0

I have dates in this format, these dates are taken from a json on http.

"2022-03-28T09:44:30Z"

The format I would like to have is this:

  • If the date is today, print Today, hh:mm
  • If the date is of type yesterday, print Yesterday, hh:mm
  • If the date is after yesterday, print dd/mm/yyyy hh:mm

enter image description here

Table(repositories) {
...
TableColumn("Last updated"){
     Text($0.updated_at)
}
...
}
Paul
  • 3,644
  • 9
  • 47
  • 113
  • You can find [here](https://stackoverflow.com/questions/35700281/date-format-in-swift) how to use the `DateFormatter`. Then, [here](https://stackoverflow.com/questions/66030777/date-components-in-swift-returns-next-year-from-end-year-date) for how to compare the dates with today or yesterday. – HunterLion Mar 28 '22 at 11:33
  • @HunterLion: I'm trying like this: https://pastebin.com/SgBuwGuT Error: https://i.stack.imgur.com/xiUlA.png – Paul Mar 28 '22 at 11:40
  • in your comment, you are applying the formatter to the `Text`, while you should apply it to the variable. Like this: `Text(formatter.string(from: $0.updated_at))`. – HunterLion Mar 28 '22 at 13:02
  • @HunterLion: error, Cannot convert value of type 'String' to expected argument type 'Date' – Paul Mar 28 '22 at 13:05

1 Answers1

1

If you can live with Yesterday at 21:51 rather than Yesterday, 21:51 create a date formatter and enable doesRelativeDateFormatting

let outputFormatter : DateFormatter = {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_GB")
    formatter.doesRelativeDateFormatting = true
    formatter.dateStyle = .medium
    formatter.timeStyle = .short
    return formatter
}()

and create a function to convert the ISO8601 string

func convertISODate(_ isoString : String) -> String {
    let formatter = ISO8601DateFormatter()
    guard let date = formatter.date(from: isoString) else { return "Unknown date format" }
    return outputFormatter.string(from: date)
}

and use it

TableColumn("Last updated"){
     Text(convertISODate($0.updated_at))
}

However I would put the entire conversion code into the model.

Side note: doesRelativeDateFormatting does not work with a custom date format specified in the dateFormat property.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Cannot convert value of type 'String' to expected argument type 'Date' – Paul Mar 28 '22 at 13:09
  • Please see the edit. – vadian Mar 28 '22 at 13:14
  • I can just do that: 'return outputFormatter.string(from: date).replacingOccurrences(of: " at", with: ",")' – Paul Mar 28 '22 at 13:22
  • With the following code it would be possible to manage also the following format `"2018-02-06T04:36:52.369420+00:00"`? – Paul Mar 28 '22 at 16:08
  • Yes, insert `formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]` after the `let formatter = ISO8601DateFormatter()` line. But not ***also***, it handles only ISO dates with fractional seconds. – vadian Mar 28 '22 at 16:36
  • But isn't there a way to make both formats work together? Because if I use `formatOptions` it works with the second format but not the first. If I don't use it, only the first format works. – Paul Mar 28 '22 at 16:53
  • Add an `if - else` expression and check the date. Set the format options of the formatter to the appropriate value. – vadian Mar 28 '22 at 17:51