2015-07-20 14 views
5

Genero un oggetto NSDate da una stringa.SWIFT: Come posso aggiungere ore all'oggetto NSDate

let dateFormatter = NSDateFormatter() 
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT") 
let stringToDate = dateFormatter.dateFromString(dateFromService) // 2015-07-20 12:00:43 +0000 

Ricevo questo valore stringa dal server web. Devo modificare il fuso orario del dispositivo personale. Vuoi aggiungere ore di questo oggetto StringToDate ma non funziona

var addHours : Int = 2 // 2 hours will be added 
var newDate = stringToDate.dateByAddingTimeInterval(addHours) 
+2

sembra che tu stia aggiungendo 2 secondi non 2 ore. timeInterval è sempre in secondi. oppure è possibile utilizzare componenti di NSDate. aggiungi 'Int = Ora * 60 * 60' –

+1

dovresti usare' NSDateComponents' per regolare data e ora. –

+0

Sì, sta aggiungendo secondi. 'NSTimeInterval' rappresenta i secondi. –

risposta

8

Stai facendo la domanda sbagliata. Questo è noto come "XY Problem". Dovresti chiedere "Come faccio a visualizzare una stringa di data che ottengo da un server web nel fuso orario locale dell'utente".

NSDate rappresenta una data/ora in una forma astratta che non contiene un fuso orario. Lo si converte in un fuso orario specifico per la visualizzazione. Non cercare di aggiungere/sottrarre ore a un NSDate per compensare i fusi orari. Questo è l'approccio sbagliato.

La risposta corretta è semplice. Crea un secondo formattatore di date e non impostare il fuso orario su GMT. Per impostazione predefinita, il fuso orario locale dell'utente.

let dateFormatter = NSDateFormatter() 
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT") 
let date = dateFormatter.dateFromString(dateFromService) 

let outputDatedateFormatter = NSDateFormatter() 
outputDatedateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" 
//leave the time zone at the default (user's time zone) 
let displayString = outputDateFormatter.stringFromDate(date) 
println("Date in local time zone = \(displayString)") 
+1

La penultima riga contiene una sintassi Objective-C :) –

+0

E mancava un punto e virgola. :) – nhgrif

+0

salvato il mio tempo, thaks ha funzionato – Mehmet

0

Se si sta facendo più spesso, controlla libreria chiamata SwiftMoment (ispirata alla stessa libreria js), che consente di eseguire le seguenti operazioni (e molto altro ancora !):

// Create date using moment library 
let myDate = moment(myString) 

// Add one hour 
let dateWithAddedHour = myDate + 1.hours 

Moment è un wrapper per esempio NSDate, mentre la durata (che è quello che si ottiene da Int.hours, Int.minutes etc.) avvolge un valore NSTimeInterval.

L'implementazione di questo dovrebbe richiedere solo un momento! (Pun intended).

13

Uso NSCalendarComponents:

let calendar = NSCalendar.currentCalendar() 
let newDate = calendar.dateByAddingUnit(
    .CalendarUnitHour, // adding hours 
    value: 2, // adding two hours 
    toDate: oldDate, 
    options: .allZeros 
) 

Utilizzando NSCalendar rappresenteranno per cose come secondo salto, salto ore, ecc

Ma, come fa notare Duncan C's answer, la semplice aggiunta di ore è sicuramente l'approccio sbagliato. Due fusi orari non saranno sempre separati dalla stessa quantità di tempo. Ancora una volta, questo è qualcosa di particolarmente vero quando prendiamo in considerazione l'ora legale. (Ad esempio, gli Stati Uniti non avviano/terminano l'ora legale negli stessi giorni dell'Europa, e l'Arizona non dispone nemmeno di do ora legale).

+0

In genere hai ragione sull'utilizzo di NSCalendar e dei tuoi amici.Ma: se "ore bisestili" si riferisce alle transizioni DST, questo è solo un problema per * giorni * e unità più grandi, non per due ore. E i secondi di salto sono generalmente ignorati dal tempo di Unix, non fa alcuna differenza se si usa NSDateComponents o si aggiunge un NSTimeInterval. –

+0

Hmm, si. Ma ci sono altri motivi per usare 'NSCalendar'. Alla fine è più leggibile ... e ti fa prendere l'abitudine di farlo scrivere in modo tale che quando si arriva a un punto in cui è indiscutibilmente * importante *, non ti sbagli. – nhgrif

+0

Sicuro. Principalmente volevo sottolineare che l'argomento "NSCalendar ecc è necessario per spiegare i secondi bisestili" è sbagliato. –

0

per SWIFT 3 è possibile utilizzare questa funzione ...

// ottenere prossima data da ore aggiungendo func

getNewDateAfterAddingHours (hoursToAdd: NSInteger, oldDate: Data) -> Int64

{

let calendar = Calendar.current 
    let newDate = calendar.date(byAdding: .hour, value: hoursToAdd, to: oldDate) 
    return Int64((newDate?.timeIntervalSince1970)!) 
}