Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

doesRelativeDateFormatting with a custom style - is it possible?

I want to use doesRelativeDateFormatting with Swift in order to get more human-readable dates, such as "today", or "tomorrow" when displaying dates on my app. However, when displaying non-relative dates, I would like to show a custom style, such as "Wed, Feb 10 '18".

So far, I could use one of the predefined dateStyle with my DateFormatter object, such as .short or .medium, but none of those display an abbreviation of both the weekday and of the month. And when using a custom format from a string, such as "EEE, MMM d yy", I lose the relative dates.

Is that a way to use both and display relative dates when they exist, and custom date for all the other dates?

like image 857
francisaugusto Avatar asked Sep 15 '25 03:09

francisaugusto


1 Answers

There's no direct way to get relative formatting and a custom format when the not using a relative format. At best you can specify the style but not the format.

One solution is to use a helper method that uses three date formatters. One that uses relative formatting with a desired style, one that isn't relative but uses the same style, and one that uses your custom format for non-relative dates.

func formatDate(_ date: Date) -> String {
    // Setup the relative formatter
    let relDF = DateFormatter()
    relDF.doesRelativeDateFormatting = true
    relDF.dateStyle = .long
    relDF.timeStyle = .medium

    // Setup the non-relative formatter
    let absDF = DateFormatter()
    absDF.dateStyle = .long
    absDF.timeStyle = .medium

    // Get the result of both formatters
    let rel = relDF.string(from: date)
    let abs = absDF.string(from: date)

    // If the results are the same then it isn't a relative date.
    // Use your custom formatter. If different, return the relative result.
    if (rel == abs) {
        let fullDF = DateFormatter()
        fullDF.setLocalizedDateFormatFromTemplate("EEE, MMM d yy")
        return fullDF.string(from: date)
    } else {
        return rel
    }
}

print(formatDate(Date()))
print(formatDate(Calendar.current.date(byAdding: .day, value: 1, to: Date())!))
print(formatDate(Calendar.current.date(byAdding: .day, value: 7, to: Date())!))

Output:

Today at 11:01:16 AM
Tomorrow at 11:01:16 AM
Tue, Feb 20, 18

If you need to format lots of dates you will want to modify this code so it creates all of the formatters once and then reuses them in this method.

like image 59
rmaddy Avatar answered Sep 17 '25 18:09

rmaddy