DateFormatter локализованный формат даты печати «PM», когда он должен быть «AM» - PullRequest
1 голос
/ 10 октября 2019

Вот уменьшенная версия моего класса форматирования:

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 я извлекаю строку времени из необработанных данных. Но это странным образом получается неправильно: я вижу «PM», где я должен видеть «AM»!

Вот необработанные данные (поступающие через 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

И это правильно. Хорошо, теперь я сделаю с моим форматером даты:

    let myf = MyDateFormatters(timeZone:timeZone).timeFormatter
    let sunriseString = myf.string(from: sunrise)
    print(sunriseString)
    // 7:22 PM

Как это может быть? Мой класс делает то же самое, за исключением того, что он использует локализованный формат даты с шаблоном. Почему я вижу «PM» вместо «AM»

1 Ответ

2 голосов
/ 10 октября 2019

Вы попали в невероятно неясную ошибку в вашем коде. Посмотрите очень, очень внимательно:

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

Таким образом, timezone, который вы используете в своем форматере, отличается от timeZone, который поступил в качестве параметра в ваш инициализатор.

ИтакВы можете спросить, что такое timezone? Почему компилятор не пометил это? Вздох, это потому, что Foundation внедряет весь C / Darwin в ваш код. timezone является значением Дарвина. Откройте time.h , и вы увидите это. Хитрость, а?

(К сожалению, я не думаю, что есть способ заставить компилятор предупреждать о подобных вещах. Использование значений Дарвина без явного пространства имен является законным, и вы не хотели бы, чтобы это было запрещенобудет.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...