问题描述
我的用例要求我在“日期和时间”设置中根据用户的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
}
现在,这解决了我的问题,但我想知道是否有更干净的方法来完成此任务。
解决方法
您可以使用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"
,
您可以使用Date
和extension
来创建get12HourFormat
get24HourFormat
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"