2014-12-23 29 views
15

Mam kilka różnych czasów ekspozycji w bazie danych i chcę wyświetlić prawidłowy czas w oparciu o strefę czasową użytkowników, tworząc przesunięcie.Dodawanie przesunięcia czasu w Swift

Otrzymuję strefę czasową użytkowników przesuniętą względem GMT i przeliczającą ją na godziny jako pierwsze.

NSTimeZone.localTimeZone().secondsFromGMT/60/60 

Następnie muszę znaleźć sposób na dodanie godzin do obiektu daty .. to jest, gdzie ja/m walczę.

let formatter = NSDateFormatter() 
    formatter.dateFormat = "HH:mm" 

    let date = formatter.dateFromString(timeAsString) 
    println("date: \(date!)") 

Następnie tworzę ciąg od daty użycia w etykiecie, aby był łatwy do odczytania z AM/PM.

formatter.dateFormat = "H:mm" 
    formatter.timeStyle = .ShortStyle 
    let formattedDateString = formatter.stringFromDate(date!) 
    println("formattedDateString: \(formattedDateString)") 

Po prostu nie mogę się dowiedzieć, jak dodawać/odejmować godziny. Rozdzieliłam ciąg znaków, ale czasami jest ujemny i nie zadziała. Być może zamierzam o tym źle.

Dzięki za pomoc.

Keith

Odpowiedz

18

Jeśli chcesz przekonwertować czas pokazać, który jest przechowywany jako ciąg w GMT, i chcesz pokazać je w lokalnej strefie czasowej użytkownika, należy nie być ręcznie regulując NSDate/Date przedmiotów . Powinieneś po prostu używać odpowiednich stref czasowych z formaterem. Na przykład, w Swift 3:

let gmtTimeString = "5:00 PM" 

let formatter = DateFormatter() 
formatter.dateFormat = "h:mm a" 
formatter.timeZone = TimeZone(secondsFromGMT: 0)   // original string in GMT 
guard let date = formatter.date(from: gmtTimeString) else { 
    print("can't convert time string") 
    return 
} 

formatter.timeZone = TimeZone.current      // go back to user's timezone 
let localTimeString = formatter.string(from: date) 

Albo w Swift 2:

let formatter = NSDateFormatter() 
formatter.dateFormat = "h:mm a" 
formatter.timeZone = NSTimeZone(forSecondsFromGMT: 0) // original string in GMT 
let date = formatter.dateFromString(gmtTimeString) 

formatter.timeZone = NSTimeZone.localTimeZone()  // go back to user's timezone 
let localTimeString = formatter.stringFromDate(date!) 
+0

"nie powinieneś ręcznie dopasowywać obiektów NSDate" - Gold! – TruMan1

4

Chciałbym użyć funkcji dateByAddingTimeInterval dodawanie i odejmowanie godzin. Dodaj do ciągu dateFormat, aby wydrukować am lub pm.

var showTimeStr = "00:00 PM" //show time in GMT as String 
let formatter = NSDateFormatter() 
formatter.dateFormat = "hh:mm a" 
let showTime = formatter.dateFromString(showTimeStr) 
showTime.dateByAddingTimeInterval(3600) //Add number of hours in seconds, subtract to take away time 
showTimeStr = formatter.stringFromDate(showTime) 
+1

Dzięki za odpowiedzi. To, co wkładasz, działa dość, musiałem po prostu dodać opcje. Teraz próbuję umieścić offset tam, gdzie masz 3600 let offsetTime = NSTimeZone.localTimeZone(). SecondsFromGMT, ale otrzymuję "Int nie jest zamienne do NSTimeInterval" Czy istnieje sposób, aby rzucić to? – user3712837

+0

Dzięki. Przygotuj i wybierz właściwą odpowiedź, jeśli zadziałała. Aby rzutować: 'let offsetTime = Int (NSTimeZone.localTimeZome(). SecondsFromGMT)'. Działanie to zadziała, ale uświadomienie sobie, że skróci ten przedział (tj. 83.96748 staje się 83, a nie 84). Jeśli chcesz zaokrąglić, a następnie rzucić, to odpowiedź na to pytanie: http://stackoverflow.com/questions/11121459/how-to-convert-nstimeinterval-to-int pomoże. –

+0

Właściwie to odejmuje tylko 7 minut i ten link nie działa tak szybko, chyba że robię to źle – user3712837

1

Oto mój ostateczny kod połączony z odpowiedzią b.Morgans. Wierzę, że to wszystko działa teraz.

let offsetTime = NSTimeInterval(NSTimeZone.localTimeZone().secondsFromGMT) 

var showTimeStr = "05:00 PM" //show time in GMT as String 
let formatter = NSDateFormatter() 
formatter.dateFormat = "h:mm a" 
let showTime = formatter.dateFromString(showTimeStr) 
let finalTime = showTime?.dateByAddingTimeInterval(offsetTime) //Add number of hours in seconds, subtract to take away time 
showTimeStr = formatter.stringFromDate(finalTime!) 
+1

Często osiągasz właściwy rezultat w ten sposób, ale przeczy on fundamentalnemu nieporozumieniu ' Obiekty NSDate 'Na przykład, z tym kodem, zmienna' showTime' nie jest godzina piąta GMT, ale raczej godzina piąta w lokalnej strefie czasowej (dla mnie w NY, godzina siedemnasta to godzina dziesiąta GMT). Oczywiście, w 'finalTime', odwracasz ten błąd, zastępując 10 pm GMT 17:00 czasu GMT, a kiedy użyjesz formatera, aby ponownie wyświetlić ten ciąg jako napis, otrzymasz czas GMT o godzinie 17, który jest poprawnie wyświetlany w Twojej lokalnej strefie czasowej (tj.w południe tutaj w NY). To niepotrzebnie mylące (a jeśli zaczniesz używać pełnych ciągów daty, czasami będziesz wyłączony o 24 godziny). – Rob

+0

Dzięki Tonie, Rob, to ma sens i chcę to zrobić we właściwy sposób i uniknąć zamieszania. – user3712837

+0

Tak, tak naprawdę używam również daty. Zasadniczo mam osobne pole w bazie danych na czas i oddzielne pole daty tj. 2014-01-01. Ale może powinienem użyć obu jednocześnie i konfiguruję zawartość bazy danych, jednak potrzebuję, aby móc również dostosować formatowanie. Więc w zasadzie cokolwiek działa najlepiej, a na koniec potrzebuję daty jako jednej etykiety i czasu jako innej w aplikacji. Dzięki. – user3712837