簡體   English   中英

NSDateFormatter:使用具有相對格式的自定義格式

[英]NSDateFormatter: Using custom format with relative formatting

我試圖以一種形式格式化NSDate s,它在適用時使用相對格式,不使用時使用星期幾:“今天”、“明天”、“星期日”、“星期一”……

問題是, 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 日星期日”的內容,但顯然這不是一個好的或通用的解決方案。

我發現的最接近的事情是這個 question ,但對於我的用例來說似乎不必要地復雜,如果可能的話,我想要更優雅的東西。

謝謝!

我會使用 3 個日期格式化程序:

  1. dateStyle = .FullStyledoesRelativeDateFormatting = true
  2. dateStyle = .FullStyledoesRelativeDateFormatting = false
  3. dateFormat = "EEEE"doesRelativeDateFormatting = false

獲取 1 和 2 的格式化字符串。如果它們不同,則使用來自 1 的字符串。如果它們相同,則獲取並使用來自 3 的字符串。

這應該適用於所有語言環境。 出於性能原因,請確保保留所有 3 個格式化程序,而不是每次都重新創建它們。

這是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 的回答不包括本地化日期,因此我添加了一個可選參數來設置 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM