Проблема с преобразованием строки в локальное время пользователя с помощью DateFormatter() Swift 4

#swift

#swift

Вопрос:

Я пытаюсь преобразовать строку в тип даты. Я пытаюсь преобразовать в местное время пользователей, но получаю странный результат. Вот функция, которую я использую, и результаты, которые я получаю. Строка, которую я использую, выглядит как «10:15 утра:

Приведенная ниже функция возвращает строку, но это просто для просмотра выходных данных, в конечном итоге она вернет дату.

 func convertTime(date: String) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "hh:mm a"
    dateFormatter.locale = Locale.current
    print(Locale.current.identifier)
    print(TimeZone.current.identifier)
    dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
    if let formattedTime = dateFormatter.date(from: date) {
        let userFormatter = DateFormatter()
        userFormatter.timeStyle = .short // Set as desired

        return userFormatter.string(from: formattedTime)
    } else {
        return "Unknown date"
    }
}
 

первая часть вывода — это входная строка, а вторая часть — преобразованное время. Я ожидал получить преобразованное время в часовом поясе Америка / Денвер, но это не так.

 en_US
America/Denver
Input String: 10:58 AM, Output String: 3:58 AM
en_US
America/Denver
Input String: 7:43 PM, Output String: 12:43 PM
en_US
America/Denver
Input String: 12:14 PM, Output String: 5:14 AM
 

Комментарии:

1. Если вам нужно местное время, вам не следует устанавливать часовой пояс на UTC

2. Вы хотите преобразовать строку, которая выглядит как «10:15 утра», в объект даты, который всегда будет текущим днем в 10:15 утра по местному часовому поясу пользователя?

Ответ №1:

Ваш вывод верен для опубликованного вами кода. Вы обрабатываете строку «10:58 AM» как время UTC в году 1. Это связано с тем, что в строке времени нет даты и потому, что вы специально установили часовой пояс UTC в форматере даты.

И вы получаете вывод «3:58 утра» по местному времени (для вас это Денвер). Обычно в Денвере UTC-7 (UTC-6 при переходе на летнее время).

Ваш код работает правильно, если ваша цель — преобразовать время UTC в местное время пользователя (в данном случае Денвера).

Если вы хотите обрабатывать исходную строку как местное время, и ваша цель — просто изменить формат, не устанавливайте значение timeZone в первом форматере даты.

Не связано, но нет необходимости использовать строку:

 dateFormatter.locale = Locale.current
 

поскольку форматировщик даты по умолчанию использует текущую локаль.