Domanda

Ho un appuntamento che è memorizzato come numero di giorni dal 1 Gennaio 1600 che ho bisogno di affrontare. Si tratta di un formato di data eredità che ho bisogno di leggere molte, molte volte nella mia applicazione.

In precedenza, ero stato la creazione di un calendario, componenti della data vuote e la data di radice in questo modo:

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

Poi, per convertire il numero intero in seguito a una data, io uso questo:

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

(non ho mai cambiare i valori di offset in qualsiasi altro luogo.)

Il problema è che sto ottenendo un tempo differente per rootDate su iOS vs Mac OS X. In Mac OS X, sto diventando mezzanotte. Su iOS, sto diventando 08:12:28. (Fino ad ora, sembra essere coerente su questo.) Quando aggiungo il mio numero di giorni dopo, i soggiorni di tempo strano.

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

Nel precedente rilascio del mio prodotto, non ho a cuore il tempo; ora faccio. Perché il tempo di strano su iOS, e che cosa devo fare? (Sto assumendo la differenza di tempo è l'ora legale).

Ho provato la regolazione delle ore, minuti e secondi di rootComponents a 0. Questo non ha alcun impatto. Se li ho impostato un valore diverso da 0, che li aggiunge 08:12:28. Mi sono chiesto se questo ha qualcosa a che fare con secondo salto o altri cambiamenti di clock cumulativa.

O è questo del tutto l'approccio sbagliato per l'uso su iOS?

È stato utile?

Soluzione 2

Sembra che la risposta giusta è quello di rendere le cose più semplici. Invece di fare un rootDate, ho solo costruire data dai componenti ogni volta. Questo non dovrebbe più lento essere, ed è ancora mantiene il codice molto vicino all'idea.

Impostazione iniziale:

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

(Ovviamente, proprietà e ivars vengono regolati.)

In seguito, per convertire in realtà una data legacy a una NSDate:

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

Questo ha questi vantaggi per me:

  1. utenti meno Ivars.
  2. E 'meno codice.
  3. Si ritorna sempre mezzanotte di quel giorno, indipendentemente dal fatto che l'ora legale è in vigore.

Altri suggerimenti

Vi immaginate ragione sul salto secondi / orologio cambia cumulativi rappresentano il problema di tempo. Sono le date voi a che fare con realtà in passato, o è puramente arbitraria un'epoca?

In entrambi i casi, si potrebbe provare la definizione di una nuova epoca che è molto più vicino a oggi (per esempio, l'epoca di cacao). Calcolare un delta giorno tra la nuova epoca e il vecchio e salvarlo come una costante. Quando è necessario elaborare una data, applicare questo delta della data e quindi utilizzare la vostra tecnica NSCalendar esistente, ma con la tua nuova epoca al posto del vecchio. Che si spera di evitare il problema di clock deriva che stai vedendo.

Si noti che iOS tiene conto delle regole molto oscuri per i diversi fusi orari. E 'più probabile che a mezzanotte, 1 gennaio 1600 nel tuo fuso orario in realtà era a 07:12:28 UTC. Ci sono stati molti casi in cui le persone si sono lamentati per i bug nelle conversioni di data e qualcuno poi capito che in realtà sono in un fuso orario che ha fatto qualche strano cambiamento di calendario molti anni fa.

È necessario sapere prima che cosa esattamente NSDate i dati rappresentano. "Numero di giorni dal 1 gennaio 1600" è una sciocchezza, perché avete bisogno di un fuso orario! Che cosa si dovrebbe fare: trovare un numero "legacy" in cui sai che giorno dovrebbe rappresentare. Ad esempio, se si "sa" che 143.671 si suppone che sia 11 Maggio 1993 nel proprio fuso orario, quindi iniziare con quella data come la data di root e add (x - 143.671) giorni di tempo per esso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top