I am trying to format NSDate
s in a form where it uses the relative format when applicable and the day of the week when not: "Today", "Tomorrow", "Sunday", "Monday", …
The problem is, NSDateFormatter
’s doesRelativeFormatting
only works when using dateStyle
, and not with dateFormat
. (Basically, I’d need the functionality of dateFormat = "EEEE"
for all days after tomorrow.)
At the moment, I’m using the following code:
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = .NoStyle
dateFormatter.dateStyle = .FullStyle
dateFormatter.doesRelativeDateFormatting = true
let dateString = dateFormatter.stringFromDate(theDate)
return dateString.componentsSeparatedByString(" ")[0]
Which just happens to work in my specific locale where NSDateFormatterStyle.FullStyle
outputs something like "Sunday 23 August 2015", but obviously that’s not a good or general solution.
The closest thing I found would be this question, but it seems unnecessarily complex for my use case, and I’d like something more elegant, if possible.
Thanks!
I'd use 3 date formatters:
dateStyle = .FullStyle
and doesRelativeDateFormatting = true
dateStyle = .FullStyle
and doesRelativeDateFormatting = false
dateFormat = "EEEE"
and doesRelativeDateFormatting = false
Get formatted strings for 1 and 2. If they are different, then use string from 1. If they are the same then get and use string from 3.
This should work reliably for all locales. For performance reasons make sure to keep all 3 formatters around instead of recreating them each time.
Here's a working extension to DateFormatter()
:
import Foundation
extension DateFormatter {
/*
* Returns a string representation of a given date in relative format.
* If the current local doesn't offer a relative format for the given date,
* then then a given format is applied.
*
* - parameter _date: The date to be formatted
* - parameter _format: The format to be applied to non-relative dates
*
* - returns: A string representing a formatted version of a given date
*/
func relativeStringWithFormat(from: Date, format: String) -> String? {
// Create date formatters
let _formatRelative = DateFormatter()
_formatRelative.dateStyle = .full
_formatRelative.doesRelativeDateFormatting = true
_formatRelative.timeStyle = .none
let _formatFull = DateFormatter()
_formatFull.dateStyle = .full
_formatFull.doesRelativeDateFormatting = false
_formatFull.timeStyle = .none
let _formatCustom = DateFormatter()
_formatCustom.dateFormat = format
_formatCustom.doesRelativeDateFormatting = false
// Get dates in available formats
let _dateRelative = _formatRelative.string(from: from)
let _dateFull = _formatFull.string(from: from)
let _dateCustom = _formatCustom.string(from: from)
// Return appropriatly formatted date/string
if _dateRelative != _dateFull {
return _dateRelative
} else {
return _dateCustom
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With