Home > Software engineering >  Swift ui date formatting
Swift ui date formatting

Time:03-29

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

CodePudding user response:

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.

CodePudding user response:

The best approuch for this would be a function, returning the desired formatted String:

func getMyFormat(_ value: String) -> String{
    let date = dateFormatter.date(from: value)
    
    guard let date = date else {
       return "error"  // provide default value
    }
    
    if Calendar.current.isDateInToday(date) || Calendar.current.isDateInYesterday(date){
        let components = Calendar.current.dateComponents([.hour,.minute], from: date)
        
        guard let hours = components.hour, let minutes = components.minute else{
            return "error"  // provide default value
        }
        
        return "\(Calendar.current.isDateInToday(date) ? "Today" : "Yesterday"), \(hours):\(minutes)"
    }
    
    return prettyFormatter.string(from: date)
}

with:

let dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
    return formatter
}()
let prettyFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "dd MMM yyyy, HH:mm"
    return formatter
}()

usage:

Text(getMyFormat($0.updated_at))
  • Related