Проблема с часовым поясом Swift 3

Кажется, метод setDefaultTimeZone больше не доступен в NSTimeZone. Кто-нибудь знает замену этому?

В моем AppDelegate.swift у меня есть:

NSTimeZone.default = TimeZone(abbreviation: "BST")!

и это работает как задумано, я думаю, потому что во всех других файлах я получаю NSTimeZone для этого значения

Теперь в моих утилитах у меня есть этот метод:

static func getDate(_ dateStr: String) -> Date {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    // dateFormatter.timeZone = TimeZone(abbreviation: "GMT")
    let date =  dateFormatter.date(from: dateStr)!
    return date
}

Итак, скажем, я даю ему ввод 2016-10-07, он возвращает мне 2016-10-06 23:00. Почему? Это будет исправлено, если вы раскомментируете строку в приведенном выше коде. Я не хочу использовать эту строку везде.

Например, в какой-то другой части моего проекта я использовал CVCalendar. Он предоставляет функцию для получения convertDate, например

func didSelectDayView(_ dayView: DayView, animationDidFinish: Bool) {
    selectedDay = dayView
    selectedDate = dayView.date.convertedDate()!
}

Здесь тоже происходит то же самое, что и раньше... то есть я нажимаю на 2016-10-08, и здесь selectedDate становится 2016-10-07 23:00.

И NSTimeZone.Default везде печатает Europe/London.

Кто-нибудь знает, почему это происходит?


person AmrataB    schedule 07.10.2016    source источник
comment
можешь показать свой проверенный код   -  person Anbu.Karthik    schedule 07.10.2016
comment
developer.apple.com/reference/foundation/nstimezone ссылайтесь на этот документ   -  person Himanshu Moradiya    schedule 07.10.2016
comment
@ Anbu.Karthik Это то, что я использовал до Swift3 в AppDelegate.swift. NSTimeZone.setDefaultTimeZone (TimeZone (аббревиатура: BST)!)   -  person AmrataB    schedule 07.10.2016
comment
@HimanshuMoradiya Я также читал эту документацию, но мой Xcode не говорит, что тип NSTimeZone не имеет члена setDefault .... вы пробовали?   -  person AmrataB    schedule 07.10.2016
comment
var UTC = NSTimeZone(имя: UTC) NSTimeZone.defaultTimeZone = UTC попробуйте это   -  person Himanshu Moradiya    schedule 07.10.2016
comment
можете ли вы показать дополнительный код   -  person Anbu.Karthik    schedule 07.10.2016
comment
@HimanshuMoradiya Я уже пробовал это. Это не работает.   -  person AmrataB    schedule 07.10.2016
comment
@AmrataB вы должны установить часовой пояс следующим образом: let locale = NSTimeZone.init (аббревиатура: BST)   -  person Jitendra Modi    schedule 07.10.2016
comment
@ Anbu.Karthik Кода больше нет. Я звонил один раз, и это сработало.   -  person AmrataB    schedule 07.10.2016
comment
@AmrataB Вы пробовали мое решение?   -  person Nirav D    schedule 07.10.2016
comment
@Nirav у меня пока ничего не работает. Поэтому я пытаюсь отладить и другие свои изменения. Я обновлю через некоторое время. Похоже, ваше решение верное. Может быть, что-то не так в моей реализации где-то.   -  person AmrataB    schedule 07.10.2016


Ответы (3)


let locale = NSTimeZone.init(abbreviation: "BST")
NSTimeZone.default = locale as! TimeZone

Попробуй это

person Jitendra Modi    schedule 07.10.2016
comment
Нет необходимости создавать экземпляр NSTimeZone, а затем преобразовывать его в TImeZone, вместо этого вы можете напрямую создать объект с TimeZone(abbreviation:), как в моем ответе. - person Nirav D; 07.10.2016
comment
Я знаю, но это немного легко понять - person Jitendra Modi; 07.10.2016

Попробуйте так.

TimeZone.ReferenceType.default = TimeZone(abbreviation: "BST")!

Редактировать: я использовал это TimeZone с DateFormatter и получил правильное BST время с датой.

TimeZone.ReferenceType.default = TimeZone(abbreviation: "BST")!
let formatter = DateFormatter()
formatter.timeZone = TimeZone.ReferenceType.default
formatter.dateFormat = "yyyy-MM-dd HH:mm"
let strDate = formatter.string(from: Date())
print(strDate)

Если вы хотите установить defaultTimeZone для объекта NSTimeZone, то в Swift 3 вы можете установить это так.

NSTimeZone.default = TimeZone(abbreviation: "BST")!
person Nirav D    schedule 07.10.2016
comment
@AmrataB Установив этот NSTimeZone.default = TimeZone(abbreviation: "BST")!, вы устанавливаете только часовой пояс по умолчанию, не используя его, и когда вы используете dateFormatter, установите с ним определенный часовой пояс, иначе он может использоваться вашей системой или локальным. - person Nirav D; 07.10.2016
comment
@AmrataB Вы понимаете, что я пытаюсь сказать? - person Nirav D; 07.10.2016
comment
Вам не нужно указывать TimeZone отдельно для DateFormatter. Он выбирает тот, который вы установили по умолчанию NSTimeZone или TimeZone по умолчанию. Моя проблема заключалась в том, что до Swift 3 он учитывал переход на летнее время, то есть, если вы печатаете часовой пояс, он использовал для этого смещения Европы / Лондона (GMT + 1) 3600 (дневной свет), и поэтому у меня все работало. Но теперь он начал возвращать Европу/Лондон или просто один час минус UTC. Это сломало все. Итак, я установил по умолчанию UTC сейчас, чтобы он не сломался снова через месяц. - person AmrataB; 08.10.2016
comment
@AmrataB Я не уверен, что вы говорите правильно, потому что я сначала попытался установить часовой пояс по умолчанию на игровой площадке с BST, а затем попытался получить текущее время, это не BST, это был мой текущий часовой пояс после установки часовой пояс с dateFormatter я смогу получить текущее время BST, может быть, вы еще раз пропустили проверку правильности понимания. - person Nirav D; 08.10.2016
comment
@AmrataB Я разместил тот же код на IBM Swift Sandbox, пожалуйста, проверьте эту ссылку один раз и попробуйте сначала запустить код, а затем раскомментируйте строку, указывающую часовой пояс для dateFormatter, вы узнаете разницу, проверьте эту ссылку swiftlang.ng.bluemix.net/#/repl/57f885c0ed27cb2723a1cb52 Сначала вы получите время этого песка IBM текущее время сервера коробки, и если вы раскомментируете, вы получите текущее время BST. - person Nirav D; 08.10.2016
comment
Я не понимаю, почему это работает: TimeZone.ReferenceType.default = TimeZone (аббревиатура: UTC)! dateFormatter.timeZone = TimeZone.ReferenceType.default, и это не удается: dateFormatter.timeZone = TimeZone (аббревиатура: UTC) для создания даты и времени в часовом поясе Z. - person James Y; 04.08.2017
comment
Спас мой проклятый день! - person Codetard; 09.10.2018

Если вы используете календарь, то

// * создать объект календаря *

var calendar = NSCalendar.current

// * определение компонентов календаря, которые также будут использоваться. Часовой пояс по UTC *

let unitFlags = Set<Calendar.Component>([.hour, .year, .minute])
calendar.timeZone = TimeZone(identifier: "UTC")!
/// Returns a time zone initialized with a given identifier.
///
/// An example identifier is "America/Los_Angeles".
///
/// If `identifier` is an unknown identifier, then returns `nil`.
public init?(identifier: String)

Идентификатор геополитического региона, определяющий часовой пояс.

общедоступный идентификатор переменной: String {get}

Примечание. Если вы хотите установить часовой пояс средства форматирования даты, вы можете использовать описанный выше подход следующим образом:

dateFormatter.timeZone = TimeZone(identifier: "UTC")!
person Wolverine    schedule 07.10.2016