【问题标题】:Is there a better way to format Date with DateFormatter according to user's "Date & Time" preference?根据用户的“日期和时间”偏好,有没有更好的方法用 DateFormatter 格式化日期?
【发布时间】:2021-01-07 12:01:30
【问题描述】:

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

确切地说,我的字符串需要忽略分钟部分,并在 12 小时制时包含“AM/PM”后缀,而在 24 小时制时正好相反。

我最近知道如何使用“jj”模板来实现这一点。 More on this(感谢@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
    }

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

【问题讨论】:

  • 举个例子说明你想如何显示时间。

标签: ios swift nsdateformatter dateformatter


【解决方案1】:

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

【讨论】:

  • 这正是我所需要的!非常感谢!
【解决方案2】:

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

【讨论】:

  • 这有一些问题。首先,这将受到用户设备区域设置和设置的影响。其次,每次调用此属性时都会创建一个新的 DateFormatter。
  • 这不尊重用户的“日期和时间”偏好/区域设置。所以说如果用户更喜欢 24 小时制/在一个遵循 24 小时制的地区,get12HourFormat 要么返回一个错误的 24 小时格式字符串,要么在某些情况下更糟糕的是 nil。这种不一致以及需要尊重用户偏好正是我采用“jj”方法的原因
猜你喜欢
  • 1970-01-01
  • 2011-03-02
  • 1970-01-01
  • 1970-01-01
  • 2021-04-22
  • 2017-09-14
  • 2011-07-30
  • 1970-01-01
  • 2019-03-03
相关资源
最近更新 更多