有没有更好的方法根据用户的 "Date & Time" 偏好使用 DateFormatter 格式化 Date?

Is there a better way to format Date with DateFormatter according to user's "Date & Time" preference?

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

准确地说,我的字符串需要忽略分钟部分,并在 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
    }

现在,这解决了我的问题,但我想知道是否有更简洁的方法来完成此任务。

您可以使用 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"

您可以使用 get12HourFormatget24HourFormat

创建 Date extension
extension Date {
    var get12HourFormat: String? {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd-MM-yyyy hh:mm a"
        return formatter.string(from: self)
    }
    
    var get24HourFormat: String? {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd-MM-yyyy HH:mm"
        return formatter.string(from: self)
    }
}

示例:

Date().get12HourFormat //"21-09-2020 07:19 PM"

Date().get24HourFormat //"21-09-2020 19:19"