Post

iOS16以上系统获取时间问题

参考:

前言

iOS开发中一般都是直接使用模拟器开发调试,等没太大问题后再真机自测一遍后发给测试验收测试,但是模拟器和真机有部分区别, 比如真机有 设置 - 通用 - 日期与时间 - 24小时制的设置,模拟器就没有,导致真机关闭24小时制变成12小时制时,在做时间格式化iOS16以上的真机会多展示一个上午下午等文字

参考搬运代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
func localizeDate(date: Date, destinationTimeZone: TimeZone? = TimeZone.current, destinationTemplate: DateTemplate) -> String {
    guard let destinationTimeZone = destinationTimeZone else {
        return "时区错误"
    }
    let formatter = DateFormatter()
    
    var formatTemplate = destinationTemplate.getTemplate()
    
    //对于一个没有国际化的App, 获取手机当前是 12小时制 还是 24小时制 "locale:" 参数一定要使用 Locale(identifier: "en_US_POSIX")
    if let aH = DateFormatter.dateFormat(fromTemplate: "j", options: 0, locale: Locale(identifier: "en_US_POSIX")),
       formatTemplate.contains("HH"),
       aH.contains("a") {
        formatTemplate = formatTemplate.replacingOccurrences(of: "HH", with: "hh")
    }
    
    //对于一个没有国际化的App, 经过实验, 用Locale.current这个方法拿到的语言地区不正确, 比如我设置的是 "简体中文-法国", Locale.current拿到的却是上一次设置的"英语-法国"
    //所以在这里使用 Locale.preferredLanguages 来拿到系统设置里的 "首选语言顺序"
    let locale = Locale(identifier: Locale.preferredLanguages.first ?? "en_US")
    
    //用下面这个方法就可获得根据系统语言地区得到的格式化样式
    //fromTemplate: 传一个临时的样式,告诉DateFormatter你需要哪些时间字段, 如: "yyyyMMdd", "MMddHHss"等, 无需携带格式.
    formatter.dateFormat = DateFormatter.dateFormat(fromTemplate: formatTemplate, options: 0, locale: locale)
    
    formatter.timeZone = destinationTimeZone
    formatter.calendar = Calendar(identifier: .gregorian)
    //注意, 这里就不能写成 Locale(identifier: "en_US_POSIX")啦. 因为手机调整到 12/24小时制的时候, 在中文显示情况下, "AM/PM" 不会转换成 "上午/下午"
    //所以, 这里就和template一样,写成相同的语言地区就可以了
    formatter.locale = locale
    let dateString = formatter.string(from: date)
    return dateString
}

输出打印示例:
20210929134455 ->  13:44:55
20210929134455 ->  29/09/2021
20210929134455 ->  29/09/2021 13:44
20210929134455 ->  29/09/2021 13:44:55

2021-09-29 13:44:56 ->  13:44:56
2021-09-29 13:44:56 ->  29/09/2021
2021-09-29 13:44:56 ->  29/09/2021 13:44
2021-09-29 13:44:56 ->  29/09/2021 13:44:56

2021-09-29T13:44:57Z ->  13:44:57
2021-09-29T13:44:57Z ->  29/09/2021
2021-09-29T13:44:57Z ->  29/09/2021 13:44
2021-09-29T13:44:57Z ->  29/09/2021 13:44:57

2022-09-29 07:44:53 +0000 ->  15:44:53
2022-09-29 07:44:53 +0000 ->  29/09/2022
2022-09-29 07:44:53 +0000 ->  29/09/2022 15:44
2022-09-29 07:44:53 +0000 ->  29/09/2022 15:44:53
This post is licensed under CC BY 4.0 by the author.