Valore imprevisto da NSDate

Sto cercando di memorizzare un orario in una data. In questo caso 1,5 secondi. Conservo l’ora nella data in questo modo:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"mm:ss.SS"]; [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]]; NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"]; 

Ma se guardo nell’area di debug, posso vedere che il valore di date1 è stato impostato su:

 date1 = (NSDate *) 0x1dd32b30 2000-01-01 01:00:01 CET 

Qualcuno potrebbe dirmi perché questo sta accadendo?

Perché c’è una massa di domande relative a NSDate su SO e hanno tutte la stessa tonalità, ti darò una risposta più lunga, probabilmente questo può essere riferito ad altre domande.

A. C’è un malinteso comune, che data è: una data è un punto sulla timeline. Non ha a che fare con ore o minuti, non ha a che fare con giorni, mesi, anni, non ha a che fare con i fusi orari.

È un punto su una linea temporale. Periodo.

(E internamente è rappresentato da un numero in virgola mobile. È una sorpresa?)

B. C’è un altro fraintendimento comune, che data è: due date, quindi punti su una timeline, sono uguali, se hanno lo stesso valore. Questo non significa che abbiano la stessa rappresentazione. Due volte possono essere uguali, anche la loro rappresentazione è completamente diversa. (Questo è quello che ti è successo.) Per un confronto non importa, quale fuso orario è in uso, previsto, $ qualunque sia. Per un confronto non importa, quale calendario è in uso, previsto o $ qualunque. Se è l’11: 11 a Colonia, in Germania (UTC + 1) sono le 10:11 a Londra, Inghilterra (UTC + 0). Questo è lo stesso tempo.

Una data è precedente se è sulla timeline prima di un’altra data.

C. Quindi quali sono queste cose divertenti come giorni, mese, fusi orari e così via? Dato che al di fuori di un episodio di star trek una volta come 26.182.382.303.127373 sarebbe difficile da capire e da gestire, gli esseri umani hanno cominciato a dare dei punti ai nomi divertenti della timeline. Queste rappresentazioni non sono la data. Sono rappresentazioni della data. È lo stesso problema con i numeri. Non sei questo scherzo?

“Ci sono 10 tipi di persone: quelli che comprendono i numeri binari e quelli che non lo fanno”.

Lo spirito dello scherzo è che 10 può essere il valore di dieci, se è scritto in notazione decimale o può essere il valore di due, scritto in notazione binaria. Nessuno può dire quale valore “10” denota a meno che non conosca il sistema numerico utilizzato per la rappresentazione. La maggior parte delle persone presuppone che sia in un sistema decimale, quindi “10” significa dieci. Questa è una convenzione popolare. E questo funziona bene da quando quasi tutto il mondo ha adottato questa convenzione. Ma: “10” può denotare due valori diversi. E viceversa: lo stesso valore può essere scritto con diverse “stringhe”: 10 in notazione decimale è uguale a 1010 in notazione binaria (ed è uguale a “2 + 8”, sqrt (100), … Quello è , perché è permesso scrivere = tra di loro.)

Sfortunatamente (no, non proprio, il tempo deve lavorare localmente in un modo semplice) per il tempo non esiste una convenzione mondiale. Se qualcuno scrive “11:11” semplicemente non puoi dire, a che ora si intende (è un punto sulla timeline). Probabilmente la persona dice implicitamente, che questo è il momento nel suo sistema di calendario nel suo fuso orario. Ma poi devi sapere, in quale posizione del mondo lo sta dicendo. Prendendo in considerazione giorno, mese e così via, probabilmente devi sapere, qual è la sua religione, perché anche in un paese persone di religioni diverse usano calendari diversi.

Dal momento che non esiste una convenzione comune a livello mondiale da un lato e Mac OS è in esecuzione su sistemi informatici in tutto il mondo, non si può presumere che un tempo stampato sia scritto in una notazione che ci si aspetta.

Pertanto è completamente, eh, non molto intelligente per confrontare le date per stringa. Non si confrontano le date, si confrontano le stringhe.

Prima di confrontare un tempo (compresa la data) devi trasformare la rappresentazione in un tempo nel tempo “reale”. Devi aggiungere informazioni sul calendario, la rappresentazione è scritta e il fuso orario (che è incluso nel calendario in Cocoa).

In Cocoa vengono utilizzate istanze di NSDateFormatter, NSCalendar, NSDateComponents per eseguire questo lavoro. Se si consente a NSDateFormatter di trasformare una rappresentazione in un’ora e viceversa, è necessario impostare il calendario. (NSDateFormatter presuppone che il calendario locale sia scelto, se non ne viene impostato uno.) È semplicemente imansible per NSDateFormatter eseguire qualsiasi lavoro di trasformazione, se non sa quale calendario utilizzare. Ed è semplicemente imansible per te.

Quindi puoi fare alcuni calcoli con esso, la data, l’ora, l’istanza di NSDate, incluso il confronto e almeno devi trasformarlo in una rappresentazione leggibile usando un calendario.

Quello che ottieni e ti lascia pensare, che è un momento sbagliato, è semplicemente l’ora giusta ma in una rappresentazione che non ti aspettavi. (-descrizione consegna sempre UTC + 0).

Provando NSLog in data restituirà la data solo in formato GMT. Quindi, se si desidera verificare se si sta ottenendo l’ora o la data corretta, convertire la data in stringa e NSLog.

 NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"mm:ss.SS"]; [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]]; NSDate *date1 = [dateFormatter dateFromString:@"00:01.50"]; NSString *dateString = [dateFormatter stringFromDate:date1]; NSlog(@"%@",dateString);