Как использовать компоненты данных для представления дополнительного 1-часового периода в конце дня для экономии света?

#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)

enter image description here

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