2017-02-11 1 views
0

Рассмотрим следующий код:Почему «ordinality (of..., In: .era, for: date)» дает тот же результат для двух дат в разных часовых поясах?

import UIKit 

let date = Date() 

guard let nycTimeZone = TimeZone(abbreviation: "EST"), 
    let nzTimeZone = TimeZone(abbreviation: "NZDT") else { 
    fatalError() 
} 
var nycCalendar = Calendar(identifier: .gregorian) 
nycCalendar.timeZone = nycTimeZone 
var nzCalendar = Calendar(identifier: .gregorian) 
nzCalendar.timeZone = nzTimeZone 

let now = Date() 

let nycDayOfEra = nycCalendar.ordinality(of: .day, in: .era, for: now) 
let nycDayOfYear = nycCalendar.ordinality(of: .day, in: .year, for: now) 

var nzDayOfEra = nzCalendar.ordinality(of: .day, in: .era, for: now) 
var nzDayOfYear = nzCalendar.ordinality(of: .day, in: .year, for: now) 

Как я пишу это, NYC время и Aukland NZ время давать разные дни. Вот так я заинтересован.

С выше коде, результаты nycDayOfYear и nzDayOfYear различны (как этого письма я получаю nycDayOfYear = 42 и nzDayOfYear = 43.)

То есть, как и ожидалось , и по желанию. (Я работал, чтобы ответить на вопрос «как рассчитать количество дней разницы в двух датах, оцененных в разных часовых поясах?».)

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

Я поэтому попытался выполнить вычисления, используя ordinality(of: .day, in: .era, for: date).

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

Почему?

Что бы более простой способ подсчитать количество календарных дней разницу между двумя датами при выраженном В РАЗЛИЧНЫХ по местному времени ЗОН? Как я уже сказал, для моего кода, который вычисляет день года, потребуется дополнительная логика для обработки дат, охватывающих границы календарного года.

Обратите внимание, что это другой вопрос, чем «Сколько дней разница между двумя датами». В моем вопросе я хочу, чтобы обе даты были выражены в разных местных часовых поясах, и меня интересует разница в календарной дате каждого из этих значений даты.

+0

«это потребует кучу беспорядочных корректировок» Подождите - почему? Различие между двумя датами, первоначально выраженными в разных часовых поясах, легко, потому что NSDate _itself_, независимо от часового пояса, является абсолютным. – matt

+0

Что означает * «разность календарных дней между двумя датами КОГДА ВЫРАЖЕН В РАЗЛИЧНЫХ МЕСТНЫХ ЗОНАХ» * означает? NSDate - это абсолютный момент времени (как сказал матовый). «Количество дней между двумя датами» относится к * конкретному * календарю и часовому поясу. –

+0

Расчет календаря по «длинным» интервалам может привести к неожиданным результатам, см. Http: // stackoverflow.com/q/41860009/1187415 для другого примера. В вашем случае 'DateComponents (calendar: ..., era: 1) .date!' Возвращает «0001-01-01 04:56:02 +0000» для календаря NY и «0000-12-31 12:20 : 56 +0000 "для календаря Новой Зеландии, т.е. разница заключается не только в разнице часовых поясов. - Моя * догадка * заключается в том, что «количество дней в эпоху» не дает разумного результата. –

ответ

0

Комментарий Мартина о расчете календаря над длинными интервалы, дающие неожиданные результаты, также являются хорошим ответом, как и для того, почему он не работает.

Я придумал код, который вычисляет требуемую разницу в значениях календарной даты между 2 датами, выраженной в конкретных временных зонах:

let date = Date() 

guard let nycTimeZone = TimeZone(abbreviation: "EST"), 
    let nzTimeZone = TimeZone(abbreviation: "NZDT") else { 
    fatalError() 
} 
var nycCalendar = Calendar(identifier: .gregorian) 
nycCalendar.timeZone = nycTimeZone 
var nzCalendar = Calendar(identifier: .gregorian) 
nzCalendar.timeZone = nzTimeZone 

let now = Date() 


let nycDateComponents = nycCalendar.dateComponents([.month, .day, .year], from: now) 
let nzDateComponents = nzCalendar.dateComponents([.month, .day, .year], from: now) 

let difference = Calendar.current.dateComponents([.day], 
    from: nycDateComponents, 
    to: nzDateComponents) 

let daysDifference = difference.days 

Сначала я конвертировать 2 даты в месяц/день/год DateComponents значений с использованием календари, установленные для их конкретного часового пояса.

Затем я использую функцию Calendar dateComponents(_:from:to:), которая позволяет рассчитать разницу между значениями 2 DateComponents в любых единицах, которые вы хотите использовать для их сравнения. (дни, в этом случае)

Смежные вопросы