#ios #swift #timezone #nsdate
#iOS #быстрый #Часовой пояс #nsdate
Вопрос:
Обычно во время экономии света в конце дня мы получаем дополнительный 1 час.
Возьмем в качестве примера часовой пояс Тегерана.
В течение 22 сентября 2021 года Тегеран будет закрыт на 1 час с 00:00 утра до 11:00 вечера.
Я написал следующий код, чтобы продемонстрировать это.
import UIKit func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) -gt; Date { var dateComponents = DateComponents() dateComponents.year = year dateComponents.month = month dateComponents.day = day dateComponents.hour = hour dateComponents.minute = minute dateComponents.second = second let date = Calendar.current.date(from: dateComponents)! return date } // During 22 September 2021, Tehran will backward by 1 hour from 00:00 AM, to 11:00 PM. let tehranTimeZone = TimeZone(identifier: "Asia/Tehran")! let oldDefault = NSTimeZone.default NSTimeZone.default = tehranTimeZone defer { NSTimeZone.default = oldDefault } let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59) let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00) let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01) // STEP 1: 2021 Sep 21 23:59:59 =gt; 1632252599.0, Tuesday, September 21, 2021 at 11:59:59 PM Iran Daylight Time print("STEP 1: 2021 Sep 21 23:59:59 =gt; (date1.timeIntervalSince1970), (date1.description(with: .current))") // STEP 2: 2021 Sep 22 00:00:00 =gt; 1632256200.0, Wednesday, September 22, 2021 at 12:00:00 AM Iran Standard Time print("STEP 2: 2021 Sep 22 00:00:00 =gt; (date2.timeIntervalSince1970), (date2.description(with: .current))") // STEP 3: 2021 Sep 22 00:00:01 =gt; 1632256201.0, Wednesday, September 22, 2021 at 12:00:01 AM Iran Standard Time print("STEP 3: 2021 Sep 22 00:00:01 =gt; (date3.timeIntervalSince1970), (date3.description(with: .current))")
От ШАГА 1 переходит к ШАГУ 2, вместо этого для их timeIntervalSince1970
различий на 1 секунду их разница составляет 3601 секунду из-за дополнительного выигрыша в 1 час.
Теперь мой вопрос в том, как мы можем использовать DateComponents
для представления дополнительного 1-часового периода в конце дня экономии света?
В другом случае, как я могу использовать DateComponents
для создания Date
файла, который способен печатать следующее?
2021 Sep 21 23:00:00 =gt; 1632252600.0, Tuesday, September 21, 2021 at 11:00:00 PM Iran Standard Time
Теперь мы понимаем, что в Тегеране в течение 21 сентября 2021 года существует 2 типа времени 23:00:00
- 23:00:00 Iran Daylight time (Epoch is 1632249000)
- 23:00:00 Iran Standard time (Epoch is 1632252600)
23:00:00 Iran Daylight time (Epoch is 1632249000)
I can represent the above using
let date = date(year: 2021, month: 09, day: 21, hour: 23, minute: 00, second: 00)
23:00:00 Iran Standard time (Epoch is 1632252600)
Я понятия не имею, как представить все вышесказанное. Поскольку я не нахожу способа DateComponents
, чтобы мы могли определить , относится ли местное время к стандартному времени или к дневному времени.
Ответ №1:
DateComponents
у вас нет часового пояса. Часовой пояс включается в него при преобразовании DateComponents
в a Date
с помощью вызова Calendar.date(from:)
. Это часовой пояс календаря, который определяет, как они DateComponents
преобразуются в a Date
.
Вместо использования Calendar.current
создайте пользовательский календарь и установите его в первый часовой пояс. (Я не мог определить часовой пояс для дневного времени Ирана. Я бы ожидал, что у него будет аббревиатура «IRDT», но это не работает.)
Допустим, у нас есть календарь irstCalendar
, установленный на Иранское стандартное время («ПЕРВОЕ»).
Если вы используете irstCalendar.date(from: dateComponents)
, вы всегда будете получать Date
данные по стандартному времени.
Рассмотрим этот код:
func date(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int, calendar: Calendar = Calendar.current) -gt; Date { var dateComponents = DateComponents() dateComponents.year = year dateComponents.month = month dateComponents.day = day dateComponents.hour = hour dateComponents.minute = minute dateComponents.second = second let date = calendar.date(from: dateComponents)! return date } guard let tehranStandardTimeZone = TimeZone(abbreviation: "IRST") else { fatalError("Can't create time zones") } var tehranSTCalendar = Calendar(identifier: .gregorian) tehranSTCalendar.timeZone = tehranStandardTimeZone let tehranDateFormatter = DateFormatter() tehranDateFormatter.dateStyle = .medium tehranDateFormatter.timeStyle = .medium tehranDateFormatter.timeZone = tehranStandardTimeZone let date1 = date(year: 2021, month: 09, day: 21, hour: 23, minute: 59, second: 59, calendar: tehranSTCalendar) let date2 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 00, calendar: tehranSTCalendar) let date3 = date(year: 2021, month: 09, day: 22, hour: 00, minute: 00, second: 01, calendar: tehranSTCalendar) print("STEP 1: 2021 Sep 21 23:59:59 =gt; (date1.timeIntervalSince1970), (tehranDateFormatter.string(from:date1))") print("STEP 2: 2021 Sep 22 00:00:00 =gt; (date2.timeIntervalSince1970), (tehranDateFormatter.string(from:date2))") print("STEP 3: 2021 Sep 22 00:00:01 =gt; (date3.timeIntervalSince1970), (tehranDateFormatter.string(from:date3))")
Это выводит:
STEP 1: 2021 Sep 21 23:59:59 =gt; 1632252599.0, Sep 21, 2021 at 11:59:59 PM STEP 2: 2021 Sep 22 00:00:00 =gt; 1632256200.0, Sep 22, 2021 at 12:00:00 AM STEP 3: 2021 Sep 22 00:00:01 =gt; 1632256201.0, Sep 22, 2021 at 12:00:01 AM
Комментарии:
1. Но для шага 1 разве правильное ожидание не должно быть 1632256199.0 вместо 1632252599.0 ? Это связано с тем, что по прошествии 1 секунды должно быть 1632256200.0