[英]NSDateFormatter: Using custom format with relative formatting
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", …我试图以一种形式格式化
NSDate
s,它在适用时使用相对格式,不使用时使用星期几:“今天”、“明天”、“星期日”、“星期一”……
The problem is, NSDateFormatter
's doesRelativeFormatting
only works when using dateStyle
, and not with dateFormat
.问题是,
NSDateFormatter
的doesRelativeFormatting
仅在使用dateStyle
时才有效,而在dateFormat
时无效。 (Basically, I'd need the functionality of dateFormat = "EEEE"
for all days after tomorrow.) (基本上,我需要在明天之后的所有日子里使用
dateFormat = "EEEE"
的功能。)
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.这恰好适用于我的特定语言环境,其中
NSDateFormatterStyle.FullStyle
输出类似“2015 年 8 月 23 日星期日”的内容,但显然这不是一个好的或通用的解决方案。
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.我发现的最接近的事情是这个 question ,但对于我的用例来说似乎不必要地复杂,如果可能的话,我想要更优雅的东西。
Thanks!谢谢!
I'd use 3 date formatters:我会使用 3 个日期格式化程序:
dateStyle = .FullStyle
and doesRelativeDateFormatting = true
dateStyle = .FullStyle
和doesRelativeDateFormatting = true
dateStyle = .FullStyle
and doesRelativeDateFormatting = false
dateStyle = .FullStyle
和doesRelativeDateFormatting = false
dateFormat = "EEEE"
and doesRelativeDateFormatting = false
dateFormat = "EEEE"
和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.获取 1 和 2 的格式化字符串。如果它们不同,则使用来自 1 的字符串。如果它们相同,则获取并使用来自 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.
出于性能原因,请确保保留所有 3 个格式化程序,而不是每次都重新创建它们。
Here's a working extension to DateFormatter()
:这是
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
}
}
}
@eranschau's answer doesn't cover localized dates, so I've added an optional parameter to set up Locale and also fixed a bug when the comparison won't work because unexpected uppercase in some cases. @eranschau 的回答不包括本地化日期,因此我添加了一个可选参数来设置 Locale,并且还修复了在某些情况下由于意外大写而无法进行比较时的错误。
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
* - parameter locale: The locale to be used for date formatting
*
* - returns: A string representing a formatted version of a given date
*/
func relativeStringWithFormat(from: Date, format: String, locale: Locale? = nil) -> String
{
// Create date formatters
let _formatRelative = DateFormatter()
_formatRelative.dateStyle = .full
_formatRelative.doesRelativeDateFormatting = true
_formatRelative.timeStyle = .none
_formatRelative.locale = locale ?? Locale.current
let _formatFull = DateFormatter()
_formatFull.dateStyle = .full
_formatFull.doesRelativeDateFormatting = false
_formatFull.timeStyle = .none
_formatFull.locale = locale ?? Locale.current
let _formatCustom = DateFormatter()
_formatCustom.dateFormat = DateFormatter.dateFormat(fromTemplate: format, options: 0, locale: locale ?? Locale.current)
// 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.caseInsensitiveCompare(_dateFull) != .orderedSame {
return _dateRelative
} else {
return _dateCustom
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.