Frage

Ich habe ein Datum, das als Anzahl der Tage seit dem 1. Januar 1600 gespeichert ist, dass ich zu behandeln. Dies ist ein Vermächtnis Datumsformat, dass ich viele, viele Male in meiner Anwendung lesen muß.

Zuvor hatte ich schon einen Kalender, leere Datum Komponenten und Wurzel Datum wie folgt zu erstellen:

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];

Dann die ganze Zahl konvertieren später zu einem Zeitpunkt, verwende ich diese:

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

(I alle Werte nie in anderswo Offset ändern.)

Das Problem ist, ich bin eine andere Zeit für rootDate auf iOS vs. Mac OS X Unter Mac OS X bekommen, ich bin immer Mitternacht. Auf iOS, ich bin immer 08.12.28. (Bisher scheint es, über diese konsequent zu sein.) Als ich später meine Anzahl der Tage hinzufügen, die seltsamen Zeitaufenthalte.

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

In der vorherige Version von meinem Produkt, habe ich über die Zeit nicht zu kümmern; Jetzt mache ich. Warum die seltsame Zeit auf iOS, und was soll ich dagegen tun? (Ich gehe davon aus der Stunde Unterschied ist DST).

Ich habe versucht, Einstellen der Stunde, Minute und Sekunde von rootComponents auf 0. Dies hat keine Auswirkungen. Wenn ich sie auf etwas anderes als 0 gesetzt, fügt es ihnen 08.12.28. Ich habe mich gefragt, ob dies etwas mit Schaltsekunden oder anderen kumulativen Takten Änderungen zu tun.

Oder ist der völlig falsche Ansatz zur Verwendung auf iOS?

War es hilfreich?

Lösung 2

Es sieht aus wie die richtige Antwort ist, die Dinge einfacher zu machen. Statt eine rootDate zu machen, ich baue gerade das Datum von Komponenten jedes Mal. Dies sollte nicht langsamer sein und ist immer noch den Code ganz in der Nähe der Idee.

Ersteinrichtung:

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

(Offensichtlich Eigenschaften und ivars eingestellt.)

Später konvertiert tatsächlich ein Vermächtnis Datum zu einem NSDate:

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

Das hat diese Vorteile für mich:

  1. Es Anwender weniger ivars.
  2. Es ist weniger Code.
  3. Es gibt immer Mitternacht an diesem Tag, und zwar unabhängig davon, ob DST in Kraft ist.

Andere Tipps

ich Sie sind Recht, über die Schaltsekunden / kumulative Uhr ändert sich vorstellen für die Zeitfrage Buchhaltung. Sind die Daten, die Sie zu tun haben in der Vergangenheit tatsächlich, oder ist es eine rein willkürliche Epoche?

In jedem Fall können Sie versuchen, eine neue Epoche zu definieren, die heute viel näher ist (sagen wir, die Cocoa-Epoche). Berechnen Sie einen Tag Delta zwischen der neuen Epoche und den alten und als Konstante speichern. Wenn Sie ein Datum verarbeiten müssen, gilt dieses Delta auf das Datum und dann Ihre vorhandene NSCalendar Technik verwenden, aber mit Ihrer neuen Epoche anstelle der alten. Das wird die Taktdrift Problem Sie sehen hoffentlich vermeiden.

Beachten Sie, dass iOS berücksichtigt sehr obskure Regeln für verschiedene Zeitzonen. Es ist sehr wahrscheinlich, dass Mitternacht, 1. JANUAR 1600 in Ihrer Zeitzone war eigentlich bei 07.12.28 UTC. Es gibt viele Fälle, in denen Menschen über Fehler in Datum Konvertierungen beschwert und dann jemand herausgefunden, dass tatsächlich sie in einer Zeitzone, die einige seltsame Kalenderänderung vor vielen Jahren gemacht.

Sie müssen sich zuerst um herauszufinden, was genau NSDate Ihre Daten darstellt. „Anzahl der Tage seit dem 1. Januar 1600“ ist Unsinn, weil Sie eine Zeitzone benötigen! Was Sie tun sollten: Finden Sie eine „Altlast“ Nummer, wo Sie wissen, was Tag es darstellen soll. wenn Sie „wissen“, zum Beispiel, dass 143.671 sollen 11. Mai 1993 in Ihrer Zeitzone sein, dann mit diesem Datum als Root-Datum und Add beginnen (x - 143.671) Tage zu.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top