Swift - получение часового пояса из строки даты ISO8601 - PullRequest
0 голосов
/ 17 мая 2018

У меня есть даты, сохраненные в базе данных в этом формате - «гггг-ММ-дд'ТХЧ: мм: ссЗ». Например, «2018-05-17T11: 15: 00 + 0330». Часовой пояс меняется, он находится в любом часовом поясе пользователя.

Я хочу получить и отобразить дату, например «17 мая 2018 11.15 утра», сохраняя дату / время в том же часовом поясе, в котором она была сохранена. Как я могу это сделать?

Я пробовал это.

let dateString = "2018-05-17T11:15:00+0330"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
//formatter.timeZone = ???
print(formatter.date(from: dateString))

Но я получаю объект Date в местном часовом поясе, и преобразование этой строки в дату также отображает дату в моем местном часовом поясе.

Есть ли что-нибудь подобное, https://stackoverflow.com/a/46216251/1373592, в Свифте?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вот небольшое расширение к TimeZone Я только что взбил. Вы можете использовать его для создания TimeZone из строки даты ISO8601. Он будет обрабатывать часовые пояса в строке в следующих форматах:

  • Z (для времени UTC)
  • + / - HH
  • + / - HHMM
  • + / - HH: мм

Вот расширение:

extension TimeZone {
    init?(iso8601: String) {
        let tz = iso8601.dropFirst(19) // remove yyyy-MM-ddTHH:mm:ss part
        if tz == "Z" {
            self.init(secondsFromGMT: 0)
        } else if tz.count == 3 { // assume +/-HH
            if let hour = Int(tz) {
                self.init(secondsFromGMT: hour * 3600)
                return
            }
        } else if tz.count == 5 { // assume +/-HHMM
            if let hour = Int(tz.dropLast(2)), let min = Int(tz.dropFirst(3)) {
                self.init(secondsFromGMT: (hour * 60 + min) * 60)
                return
            }
        } else if tz.count == 6 { // assime +/-HH:MM
            let parts = tz.components(separatedBy: ":")
            if parts.count == 2 {
                if let hour = Int(parts[0]), let min = Int(parts[1]) {
                    self.init(secondsFromGMT: (hour * 60 + min) * 60)
                    return
                }
            }
        }

        return nil
    }
}

И тест:

print(TimeZone(iso8601: "2018-05-17T11:15:00+0330"))

Вы можете объединить этот синтаксический анализ и форматирование, чтобы получить конечный результат в исходном часовом поясе.

let dateString = "2018-05-17T11:15:00+0330"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
formatter.locale = Locale(identifier: "en_US_POSIX")
if let date = formatter.date(from: dateString), let tz = TimeZone(iso8601: dateString) {
    let newFmt = DateFormatter()
    newFmt.dateStyle = .medium
    newFmt.timeStyle = .short
    newFmt.timeZone = tz
    let newString = newFmt.string(from: date)
    print(newString)
}
0 голосов
/ 17 мая 2018

Что вы действительно пытаетесь сделать, так это игнорировать часовой пояс.

Вы можете просто удалить последние 5 символов из строки даты, проанализировать ее в одном формате и отформатировать в другом формате.:

let dateString = "2018-05-17T11:15:00+0330"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
let date = formatter.date(from: String(dateString.dropLast(5)))! // note the stripping off here
formatter.dateFormat = "MMMM d, yyyy hh.mma"
print(formatter.string(from: date))

Обратите внимание, что вы не можете сравнить эту дату с другими датами, поскольку вы удалили ее часовой пояс.

Кроме того, SwiftDate аналогиченбиблиотека в JodaTime.

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