2011-09-20 19 views
14

Ho un oggetto NSDate. Diciamo che rappresenta "2011/01/10"Ottieni NSDate da NSDate corretto con fuso orario

NSDate *date = [df dateFromString:@"2011-10-01 00:00:00"]; 

Tale data si traduce in "2011-09-30 22:00:00" a causa della mia fuso orario.

Domanda: Come si ottiene un nuovo oggetto Date che rappresenta "2011-10-01 00:00:00" nel fuso orario locale?

+0

provare \t [df setLocale: [NSLocale currentLocale]]; –

risposta

27

NSDate rappresenta solo un punto di assoluto nel tempo. Non ha alcun concetto di fuso orario o calendario. Quando crei un'istanza NSDate è solo un numero di secondi dal 1 ° gennaio 2001 GMT! Non importa se ti trovi a New York, Tokyo, Barcellona o Gerusalemme.

Nell'esempio, si istanzia l'NSDate basato su GMT, ma [date description] (utilizzato in NSLog) lo traduce nell'ora locale. Lì hai la discrepanza.

Quindi ci sono due parti a prendere in considerazione:

1. creazione NSDate utilizzando NSCalendar e NSTimeZone

Se si sta creando una data manualmente è necessario specificare il calendario (2012 in gregoriano, ma 5772 in ebraico) e fuso orario (22:00 ora di Londra, ma 7:00 ora di Sydney).

// Use the user's current calendar and time zone 
NSCalendar *calendar = [NSCalendar currentCalendar]; 
[calendar setTimeZone: [NSTimeZone systemTimeZone]]; 

// Specify the date components manually (year, month, day, hour, minutes, etc.) 
NSDateComponents *timeZoneComps=[[NSDateComponents alloc] init]; 
[timeZoneComps setHour:22]; 
[timeZoneComps setMinute:0]; 
[timeZoneComps setSecond:0]; 
// ... year, month, ... 

// transform the date compoments into a date, based on current calendar settings 
NSDate *date = [calendar dateFromComponents:timeZoneComps]; 

A questo punto data memorizza il punto esatto nel tempo (in secondi) che rappresenta il calendario attuale.

2. Uscita NSDate utilizzando NSDateFormatter

Per un'uscita controllato del vostro NSDate è necessario NSDateFormatter, che viene utilizzato per convertire le date in stringhe.

Sulla base di Apple NSDateFormatter Class Reference documentazione

Ci sono molti attributi che si possono ottenere e impostare una data stile formattatore, ... siete invitati, tuttavia, non modificare le singole impostazioni . Invece si dovrebbe accettare le impostazioni predefinite stabiliti inizializzazione e specificare il formato utilizzando setDateStyle :, setTimeStyle:

Questo è particolarmente importante per l'uscita, che è diverso per ogni locale. Per impostazione predefinita NSDateFormatter osserva le impostazioni locali dell'utente corrente. Quindi lo stesso NSDate potrebbe essere 22.11.2011 18:33:19 o Nov 22, 2011 6:33:19 PM o 2011-11-22 下午6:33:19 o anche २२-११-२०११ ६:३३:१९ अपराह्, tutti per lo stesso input e con lo stesso codice.

E il codice:

// NSDate *date -> NSString *dateString 

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
[dateFormatter setDateStyle:NSDateFormatterMediumStyle]; 
[dateFormatter setTimeStyle:NSDateFormatterShortStyle]; 

// Medium style date, short style time => "Nov 23, 1937 3:30pm" 
NSString *dateString = [dateFormatter stringFromDate:date]; 

Oppure si potrebbe trasformare utilizzando il metodo di classe localizedStringFromDate:dateStyle:timeStyle:

Spero che questo chiarisce il problema.

6

[NSDate date] restituisce la data in GMT.

Quando si affermare:

Tale data si traduce in "2011-09-30 22:00:00" a causa della mia fuso orario.

È quello da NSLog o NSDateFormatter? Non fare affidamento su [date description] utilizzato da NSLog, prende in considerazione il fuso orario locale, utilizzare NSDateFormatter. NSDateFormatter ha un metodo setTimeZone.

Da docs Apple su [date description]:

La rappresentazione non è garantito a rimanere costante attraverso diverse versioni del sistema operativo. Per formattare una data, si necessario utilizzare un oggetto data formattatore invece