DateFormatter本地化的日期格式应为“ AM”时打印“ PM”

时间:2019-10-10 17:14:53

标签: swift

这是我的格式化程序类的简化版本:

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”

1 个答案:

答案 0 :(得分:2)

您已经被代码中一个难以理解的错误所吸引。看起来非常非常紧密:

init(timeZone:Int) {
//       ^
    self.timeFormatter = {
        let tz = TimeZone(secondsFromGMT: timezone)
//                                            ^

因此,格式化程序中使用的timezone与作为参数传入初始化程序的timeZone不同。

因此,您可能会问,是什么 timezone?编译器为什么不标记它?叹气,是因为Foundation将整个C / Darwin注入了您的代码。 timezone是达尔文值。打开 time.h ,您会看到它。整rick,嗯?

(不幸的是,我不认为有一种方法可以使编译器对这种情况发出警告。使用没有显式命名空间的Darwin值是合法的,并且您不希望它不存在。)