这是我的格式化程序类的简化版本:
class MyDateFormatters {
let timeFormatter : DateFormatter
init(timeZone:Int) {
self.timeFormatter = {
let tz = TimeZone(secondsFromGMT: timezone)
let df = DateFormatter()
df.timeZone = tz
df.setLocalizedDateFormatFromTemplate("hhmm")
return df
}()
}
}
在我的viewDidLoad
中,我是从原始数据中得出时间字符串。但是它以一种奇怪的方式出现了错误:我在应该看到“ AM”的地方看到了“ PM”!
这是原始数据(通过JSON出现):
let timeZone = -14400
let sunriseRaw = 1570620145
现在,如果只是制作一个普通的香草日期格式化程序并打印出sunriseRaw
,这就是我得到的:
let sunrise = Date(timeIntervalSince1970: Double(sunriseRaw))
let df = DateFormatter()
df.dateFormat = "hh:mm a"
df.timeZone = TimeZone(secondsFromGMT: timeZone)
print(df.string(from: sunrise))
// 07:22 AM
那是正确的。好的,现在我将使用 my 日期格式化程序:
let myf = MyDateFormatters(timeZone:timeZone).timeFormatter
let sunriseString = myf.string(from: sunrise)
print(sunriseString)
// 7:22 PM
怎么可能?除了使用带有模板的本地化日期格式外,我的班级正在做完全相同的事情。为什么我看到的是“ PM”而不是“ AM”
答案 0 :(得分:2)
您已经被代码中一个难以理解的错误所吸引。看起来非常非常紧密:
init(timeZone:Int) {
// ^
self.timeFormatter = {
let tz = TimeZone(secondsFromGMT: timezone)
// ^
因此,格式化程序中使用的timezone
与作为参数传入初始化程序的timeZone
不同。
因此,您可能会问,是什么 timezone
?编译器为什么不标记它?叹气,是因为Foundation将整个C / Darwin注入了您的代码。 timezone
是达尔文值。打开 time.h ,您会看到它。整rick,嗯?
(不幸的是,我不认为有一种方法可以使编译器对这种情况发出警告。使用没有显式命名空间的Darwin值是合法的,并且您不希望它不存在。)