Question

J'ai une date qui est stocké comme un certain nombre de jours depuis le 1er Janvier, 1600 que je dois traiter. Ceci est un format de date de l'héritage que je dois lire beaucoup, beaucoup de fois dans ma demande.

Auparavant, j'avais été la création d'un calendrier, des composants de date vides et la date de la racine comme ceci:

self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
                    ] autorelease];
id rootComponents = [[[NSDateComponents alloc] init] autorelease];
[rootComponents setYear: 1600];
[rootComponents setMonth: 1];
[rootComponents setDay: 1];
self.rootDate = [gregorian dateFromComponents: rootComponents];
self.offset = [[[NSDateComponents alloc] init] autorelease];

Ensuite, pour convertir l'entier plus tard à une date, j'utilise ceci:

[offset setDay: theLegacyDate];
id eventDate = [gregorian dateByAddingComponents: offset
                                          toDate: rootDate
                                         options: 0];

(je ne changer aucune valeur en offset nulle part ailleurs.)

Le problème est que je reçois un autre moment pour rootDate sur iOS vs Mac OS X. Sous Mac OS X, je reçois minuit. Sur iOS, je suis en train de 8:12:28. (Jusqu'à présent, il semble être cohérent à ce sujet.) Quand j'ajouter mon nombre de jours plus tard, les séjours de temps bizarre.

OS       | legacyDate | rootDate                  | eventDate
======== | ========== | ==========================|==========================
Mac OS X | 143671     | 1600-01-01 00:00:00 -0800 | 1993-05-11 00:00:00 -0700
iOS      | 143671     | 1600-01-01 08:12:28 +0000 | 1993-05-11 07:12:28 +0000

Dans la version précédente de mon produit, je ne se soucie pas du temps; maintenant oui. Pourquoi le temps étrange sur iOS, et que dois-je faire? (Je suppose la différence d'heure est l'heure d'été).

J'ai essayé d'installer l'heure, minute et seconde de rootComponents à 0. Cela n'a pas d'impact. Si je les mets à autre chose que 0, il les ajoute à 08:12:28. Je me demandais si cela a quelque chose à voir avec les secondes sautées ou d'autres changements d'horloge cumulative.

Ou est-ce tout à fait la mauvaise approche à utiliser sur iOS?

Était-ce utile?

La solution 2

Il semble que la bonne réponse est de rendre les choses plus simples. Au lieu de faire un rootDate, je viens de construire la date à partir de composants à chaque fois. Cela ne devrait pas être plus lent, et garde toujours le code très proche de l'idée.

Configuration initiale:

self.gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar
                    ] autorelease];
self.components = [[[NSDateComponents alloc] init] autorelease];
[components setYear: 1600];
[components setMonth: 1];

(De toute évidence, les propriétés et Ivars sont ajustées.)

Plus tard, convertir en fait une date de l'héritage à un NSDate:

[components setDay: 1 + theLegacyDate];
id eventDate = [gregorian dateFromComponents: components];

a ces avantages pour moi:

  1. moins d'utilisateurs Ivars.
  2. Il est moins de code.
  3. Il retourne toujours minuit ce jour-là, que l'heure d'été est en vigueur.

Autres conseils

Je vous imagine avez raison sur les secondes bissextiles / changements d'horloge cumulatifs représentant la question du temps. Les dates vous avez affaire fait dans le passé, ou est-ce purement une époque arbitraire?

Dans les deux cas, vous pouvez essayer de définir une nouvelle époque qui est beaucoup plus proche de nos jours (par exemple, l'époque Cocoa). Calculer un delta de jour entre la nouvelle époque et l'ancien et l'enregistrer comme une constante. Lorsque vous avez besoin pour traiter une date, appliquer ce delta à la date, puis utilisez votre technique NSCalendar existante, mais avec votre nouvelle époque au lieu de l'ancien. Cela, nous l'espérons éviter le problème de la dérive d'horloge vous Seeing êtes la.

Notez que iOS prend en compte des règles très obscures pour différents fuseaux horaires. Il est fort probable que minuit, 1 janvier 1600 dans votre fuseau horaire était en fait à 07:12:28 UTC. Il y a eu de nombreux cas où les gens se sont plaints de bogues dans les conversions de date et quelqu'un alors compris que en fait, ils sont dans un fuseau horaire qui a fait un changement de calendrier étrange il y a plusieurs années.

Vous devez savoir d'abord ce que exact NSDate vos données représente. « Nombre de jours depuis le 1 janvier 1600 » est un non-sens, parce que vous avez besoin d'un fuseau horaire! Ce que vous devez faire: Trouver un numéro « héritage » où vous savez quel jour il est censé représenter. Par exemple, si vous « savez » que 143671 est censé être le 11 mai 1993 dans votre fuseau horaire, puis commencer à cette date que la date de racine et ajouter (x - 143671) jours à elle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top