2017-01-25 1 views
0

создать экземпляр DateComponents, используя следующий код:Почему Calendar.date (from: DateComponents) добавляет время?

let dateComponents = DateComponents(
      calendar: .current, 
      timeZone: Calendar.current.timeZone, 
      era: nil, 
      year: nil, 
      month: nil, 
      day: nil, 
      hour: 9, 
      minute: 0, 
      second: 0, 
      nanosecond: 0, 
      weekday: 2, 
      weekdayOrdinal: nil, 
      quarter: nil, 
      weekOfMonth: nil, 
      weekOfYear: nil, 
      yearForWeekOfYear: nil) 

Я затем распечатать dateComponents объект и получить следующий (ожидаемый) результат:

календарь: Григорианский (текущая) Часовой пояс: Европа/Лондон (текущий) час: 9 минут: 0 секунд: 0 наносекунда: 0 день недели: 2 isLeapMonth: false

Сразу после этого я печатаю дату, созданную нами ИНГ следующий код:

print(Calendar.current.date(from: dateComponents)!) 

К моему большому разочарованию и тщательное несчастьем, следующее выводится:

0001-01-01 09: 0 1:15 +0000

Функция date(from: dateComponents), как представляется, добавила чуть более минуты к dateComponents перед созданием даты из них.

Благодарим за любую помощь заранее.

+0

Какого смысл создание даты, которая имеет только один час и не другие компоненты? Какова ваша цель? – rmaddy

+0

Вам нужно указать дату, иначе она вернется к году 1 и будет иметь огромное временное смещение. Просто выберите что-то вроде эры 1 год 2001 месяц 1 день 1 –

+1

BTW вы можете опустить параметры, которые вы не устанавливаете ни в какое значение (nil по умолчанию), если вы сохраняете один и тот же порядок. –

ответ

3

NSDate имеет некоторые странные и недокументированные формы поведения для древних дат. Изменения, похоже, произошло около 1895:

for year in 1890..<1900 { 
    // January 1 of each year @ 9AM 
    let dateComponents = DateComponents(
     calendar: .current, 
     timeZone: Calendar.current.timeZone, 
     year: year, 
     month: 1, 
     day: 1, 
     hour: 9) 

    if dateComponents.isValidDate { 
     print(dateComponents.date!) 
    } 
} 

Мой календарь григорианский и часовой пояс EDT (UTC -0500). Это выход:

1890-01-01 14:17:32 +0000 
1891-01-01 14:17:32 +0000 
1892-01-01 14:17:32 +0000 
1893-01-01 14:17:32 +0000 
1894-01-01 14:17:32 +0000 // not correct 
1895-01-01 14:00:00 +0000 // correct 
1896-01-01 14:00:00 +0000 
1897-01-01 14:00:00 +0000 
1898-01-01 14:00:00 +0000 
1899-01-01 14:00:00 +0000 

Так за года до 1895 года, Apple как-то добавлена ​​17 минут и 32 секунды до моего времени. У вас другое смещение, которое, вероятно, связано с вашими настройками локали.

Я не нашел ничего исторического события о григорианском календаре в 1895 году. This question упоминает, что Великобритания начала переходить на GMT, а Гринвичская обсерватория начала корректировать стандарты даты и времени на Британских островах в 1890-х годах, чтобы иметь возможность учтено это смещение. Возможно, кто-то может углубиться в исходный код для Date/NSDate и понять это?


Если вы хотите использовать DateComponent для хранения повторяющегося расписания, используйте nextDate(after:matching:matchingPolicy:) найти следующее вхождение вашего графика:

let dateComponents = DateComponents(calendar: .current, timeZone: .current, hour: 9, weekday: 2) 

// 9AM of the next Monday 
let nextOccurance = Calendar.current.nextDate(after: Date(), matching: dateComponents, matchingPolicy: .nextTime)! 
+2

В Германии часы были повернуты на 6 минут и 32 секунды 1 апреля 1893 года: https://www.timeanddate.com/time/change/germany/berlin ? год = 1893. Возможно, что-то подобное произошло в вашем часовом поясе? –

+0

Это интересная теория, ребята, спасибо. Я использую его для хранения информации о расписании, которое повторяется ежедневно или еженедельно, поэтому другие компоненты, такие как дата и месяц, не важны для меня. Можете ли вы подумать о лучшем способе представления графика, которое может повторяться ежедневно, в определенное время или еженедельно, в определенные дни и определенное время? –