当前TimeZone不生效,如何从字符串获取设备时区的正确日期时间?
解决DateFormatter解析后获取设备时区对应时间的问题
首先得理清一个关键概念:Date对象本身是没有时区属性的,它本质上只是一个代表某个时间点的时间戳(相对于UTC 2001年1月1日的秒数)。你直接print(date)看到的UTC时间,只是Date默认的字符串表示方式,并不代表这个时间点本身是UTC的——它其实已经正确对应了你输入的PDT时间,只是显示格式是UTC而已。
如果你想要得到设备时区(洛杉矶时区)对应的可读日期时间字符串,只需要再用一次DateFormatter,把这个Date对象格式化成你想要的本地时区格式就行,步骤如下:
- 保持你原来的解析逻辑不变,先正确解析出
Date对象(这一步你已经做对了,因为指定了正确的dateFormat和时区,能准确把PDT时间转换成对应的时间戳) - 创建一个用于展示的
DateFormatter,设置时区为设备当前时区(其实默认就是TimeZone.current,可以省略这一步),然后指定你想要的输出格式,调用string(from:)方法生成字符串。
完整代码示例:
let timeStamp = "2018-03-27 21:10:55 PDT" let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz" dateFormatter.timeZone = TimeZone.current // 解析时间字符串得到Date对象(时间点是正确的,只是默认显示为UTC) guard let date = dateFormatter.date(from: timeStamp) else { print("Failed to parse the timestamp") return } // 将Date转换为设备时区的字符串 let localDisplayFormatter = DateFormatter() localDisplayFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" // 自定义你想要的格式 // 以下这行可以省略,因为DateFormatter默认时区就是当前设备时区 localDisplayFormatter.timeZone = TimeZone.current let localTimeString = localDisplayFormatter.string(from: date) print(localTimeString) // 输出: 2018-03-27 21:10:55(符合洛杉矶时区的时间)
如果你需要获取具体的日期组件(比如年、月、日、小时等设备时区下的数值),可以用Calendar来处理:
let calendar = Calendar.current let components = calendar.dateComponents(in: TimeZone.current, from: date) // 可以获取各个组件,比如: print(components.year!) // 2018 print(components.month!) // 3 print(components.day!) // 27 print(components.hour!) // 21
总结一下:Date本身是时区无关的时间点,你看到的UTC输出只是默认的显示格式。要得到设备时区对应的时间表现,要么用DateFormatter生成字符串,要么用Calendar提取本地时区的日期组件。
内容的提问来源于stack exchange,提问作者KevinVuD
相关产品推荐
相关产品推荐

