NSDateFormatter:使用具有相对格式的自定义格式
Posted
技术标签:
【中文标题】NSDateFormatter:使用具有相对格式的自定义格式【英文标题】:NSDateFormatter: Using custom format with relative formatting 【发布时间】:2015-08-21 15:20:48 【问题描述】:我正在尝试将NSDate
s 格式化为一种在适用时使用相对格式而在不适用时使用星期几的格式:“今天”、“明天”、“星期日”、“星期一”……
问题是,NSDateFormatter
的 doesRelativeFormatting
仅在使用 dateStyle
时有效,而在 dateFormat
时无效。 (基本上,我需要 dateFormat = "EEEE"
的功能来维持后天的所有日子。)
目前,我正在使用以下代码:
let dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = .NoStyle
dateFormatter.dateStyle = .FullStyle
dateFormatter.doesRelativeDateFormatting = true
let dateString = dateFormatter.stringFromDate(theDate)
return dateString.componentsSeparatedByString(" ")[0]
这恰好在我的特定语言环境中工作,NSDateFormatterStyle.FullStyle
输出类似“2015 年 8 月 23 日星期日”的内容,但显然这不是一个好的或通用的解决方案。
我找到的最接近的东西是 this question,但对于我的用例来说,它似乎不必要地复杂,如果可能的话,我想要更优雅的东西。
谢谢!
【问题讨论】:
【参考方案1】:我会使用 3 个日期格式化程序:
dateStyle = .FullStyle
和 doesRelativeDateFormatting = true
dateStyle = .FullStyle
和 doesRelativeDateFormatting = false
dateFormat = "EEEE"
和 doesRelativeDateFormatting = false
获取 1 和 2 的格式化字符串。如果它们不同,则使用来自 1 的字符串。如果它们相同,则获取并使用来自 3 的字符串。
这应该适用于所有语言环境。出于性能原因,请确保保留所有 3 个格式化程序,而不是每次都重新创建它们。
【讨论】:
【参考方案2】:这是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
【讨论】:
【参考方案3】:@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
【讨论】:
以上是关于NSDateFormatter:使用具有相对格式的自定义格式的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 nsdateformatter 将 nsdate 转换为另一种格式
使用 NSDateFormatter 格式化月份和年份返回无效日期
NSDateFormatter dateFromString 格式字符串问题
将事件添加到日历时,NSDateFormatter 未正确格式化日期
使用 setDoesRelativeDateFormatting: YES 和 setDateFormat: 与 NSDateFormatter