2017-02-11 5 views
0

Consultez le code suivant:Pourquoi `l'ordinalité (de: .day, dans: .era, pour: date)` donne-t-elle le même résultat pour 2 dates dans différents fuseaux horaires?

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) 

Comme je l'écris ces lignes, le temps de New York et Aukland temps NZ donner des jours différents. C'est le cas, je suis intéressé par.

Avec le code ci-dessus, les résultats pour nycDayOfYear et nzDayOfYear sont différentes (de cette écriture, je reçois nycDayOfYear = 42 et nzDayOfYear = 43.)

qui est comme prévu et comme désiré. (Je travaillais pour répondre à une question "comment puis-je calculer le nombre de jours de différence dans deux dates évaluées dans différents fuseaux horaires?"

Cependant, il faudrait un tas d'ajustements désordonnés pour faire le jour ci-dessus calcul de l'année et déterminer le nombre de jours de différence entre ces dates locales lorsqu'elles couvrent les limites de l'année. J'ai donc essayé de faire les calculs en utilisant ordinality(of: .day, in: .era, for: date)

Cependant, les calculs basés sur l'ère du calendrier donnent la même valeur quel que soit le fuseau horaire du calendrier utilisé pour faire le calcul.

Pourquoi est-ce?

Quelle serait une façon plus simple de calculer le nombre de jours de calendrier différence entre deux dates QUAND EXPRIME EN ZONES DE TEMPS LOCALES DIFFÉRENTS? Comme je l'ai dit, mon code qui calcule le jour de l'année aurait besoin d'une logique supplémentaire pour gérer les dates qui couvrent les limites de l'année civile.

Notez qu'il s'agit d'une question différente de "Combien de jours différence existe-t-il entre 2 dates". Dans ma question, je veux que les deux dates soient exprimées dans différents fuseaux horaires locaux, et je m'intéresse à la différence dans la date du calendrier de chacune de ces dates.

+0

"il faudrait un tas de réglages désordonnés" Attendez - pourquoi le ferais-il? Il est facile de faire la différence entre deux dates exprimées à l'origine dans des fuseaux horaires différents, car le NSDate _itself_, quel que soit le fuseau horaire _original_, est absolu. – matt

+0

Que signifie * "nombre de jours calendaires de différence entre deux dates QUAND EXPRIMÉES DANS DIFFÉRENTES ZONES LOCALES" *? NSDate est un point absolu dans le temps (comme cela vient d'être dit). "Nombre de jours entre deux dates" fait référence à un calendrier et à un fuseau horaire * spécifiques. –

+0

Les calculs de calendrier sur des intervalles "longs" peuvent produire des résultats inattendus, voir http: // stackoverflow.com/q/41860009/1187415 pour un autre exemple. Dans votre cas, 'DateComponents (calendar: ..., era: 1) .date!' Renvoie "0001-01-01 04:56:02 +0000" pour le calendrier NY et "0000-12-31 12:20 : 56 +0000 "pour le calendrier NZ, c'est-à-dire que la différence n'est pas seulement la différence des fuseaux horaires. - Ma * estimation * est que "nombre de jours dans l'ère" ne donne aucun résultat sensible. –

Répondre

0

Les commentaires de Martin sur les calculs de calendrier sur longs intervalles donnant des résultats inattendus est une aussi bonne réponse que tout autre pourquoi cela ne fonctionne pas.

Je suis venu avec un code qui calcule la différence souhaitée dans les valeurs de date de calendrier entre 2 dates exprimées dans des fuseaux horaires spécifiques:

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 

D'abord, je convertir les 2 dates pour mois/jour/année DateComponents valeurs à l'aide calendriers définis sur leur fuseau horaire spécifique.

Ensuite, j'utilise la fonction Calendrier dateComponents(_:from:to:), qui vous permet de calculer la différence entre 2 DateComponents valeurs, quelles que soient les unités que vous souhaitez utiliser pour les comparer. (jours, dans ce cas)