首页 > 解决方案 > 根据用户的“日期和时间”偏好,有没有更好的方法用 DateFormatter 格式化日期?

问题描述

我的用例要求我在“日期和时间”设置中根据用户的 12 小时/24 小时偏好显示不同格式的字符串。

准确地说,我的字符串需要忽略分钟部分,并在 12 小时时间包含“AM/PM”后缀,而对 24 小时时间则完全相反。

我最近知道如何使用“jj”模板来实现这一点。更多信息(感谢@larme)

这是我的方法:

    let df = DateFormatter()
    df.setLocalizedDateFormatFromTemplate("jj:mm") // As of current time in my locale, this'll display "17:01"
    df.locale = .current
    
    if df.string(from: passedDate).count > 5 {
        // User has 12-hour time setting i.e: The string has AM/PM suffix
        df.setLocalizedDateFormatFromTemplate("jj") // Setting this will ignore the minutes and provide me with the hour and the AM/PM suffix i.e: "5 PM" according to current time
    }

现在,这解决了我的问题,但我想知道是否有更清洁的方法来完成这项工作。

标签: iosswiftnsdateformatterdateformatter

解决方案


您可以使用DateFormatter静态方法dateFormat(fromTemplate tmplate: String, options opts: Int, locale: Locale?) -> String?传递j格式和.current语言环境并检查它是否包含“a”:

extension DateFormatter {
    static var is24Hour: Bool {
        dateFormat(fromTemplate: "j", options: 0, locale: .current)?.contains("a") == false
    }
}

extension Formatter {
    static let customHour: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.setLocalizedDateFormatFromTemplate("jj")
        return dateFormatter
    }()
}

extension Date {
    var customHour: String { Formatter.customHour.string(from: self) }
}

DateFormatter.is24Hour  // false
Date().customHour       // "11 AM"


请注意,除非用户在格式化程序初始化后更改它,否则无需检查 24 小时设置是否打开。如果想确保它也反映了这一点:


extension Formatter {
    static let date = DateFormatter()
}

extension Date {
    var customHour: String {
        Formatter.date.setLocalizedDateFormatFromTemplate("jj")
        return Formatter.date.string(from: self)
    }
}

Date().customHour       // "11 AM"

推荐阅读