【问题标题】:NSDateFormatter: Using custom format with relative formattingNSDateFormatter:使用具有相对格式的自定义格式
【发布时间】:2015-08-21 15:20:48
【问题描述】:

我正在尝试将NSDates 格式化为一种在适用时使用相对格式而在不适用时使用星期几的格式:“今天”、“明天”、“星期日”、“星期一”……

问题是,NSDateFormatterdoesRelativeFormatting 仅在使用 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,但对于我的用例来说,它似乎不必要地复杂,如果可能的话,我想要更优雅的东西。

谢谢!

【问题讨论】:

    标签: ios swift cocoa cocoa-touch


    【解决方案1】:

    我会使用 3 个日期格式化程序:

    1. dateStyle = .FullStyledoesRelativeDateFormatting = true
    2. dateStyle = .FullStyledoesRelativeDateFormatting = false
    3. 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
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2013-09-01
          • 2016-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-05
          • 1970-01-01
          • 1970-01-01
          • 2013-10-24
          相关资源
          最近更新 更多