Ich habe die folgende Zeichenfolge:
let dateString = "2018-04-18T04:54:00-04:00"
Ich initialisiere ein Date
über das ISO8601DateForamtter
wie folgt:
let formatter = ISO8601DateFormatter()
let date = formatter.date(from: dateString)
Wenn ich das Datum drucke, erhalte ich Folgendes:
Apr 18, 2018 at 1:54am
Der Formatierer konvertiert die Zeit automatisch in meine Ortszeit. Wie kann ich verhindern, dass meine Zeitzone berücksichtigt wird? Ich möchte beispielsweise, dass das Objekt Date
stattdessen Folgendes anzeigt:
Apr 18, 2018 at 4:54am
5 Antworten
Mit ISO8601
bedeutet 2018-04-18T04:54:00-04:00
2018-04-18 04:54:00
in GMT -4h
. Um die Uhrzeit so zu drucken, wie sie in der ursprünglichen Zeichenfolge enthalten ist, müssen Sie einen Datumsformatierer mit der spezifischen Zeitzone -4
erstellen.
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: -4 * 60 * 60)
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
print(dateFormatter.string(from: date))
Sie erhalten
2018-04-17 04:54:00
Zu Ihrer Information, ich füge einen Link für ISO8601 hinzu
Sie müssen die Zeitzone aus Ihrer Datumszeichenfolge analysieren und damit die Zeitzone aus Ihrem Datumsformatierer festlegen:
func secondsFromGMT(from string: String) -> Int {
guard !string.hasSuffix("Z") else { return 0 }
let timeZone = string.suffix(6)
let comps = timeZone.components(separatedBy: ":")
guard let hours = comps.first,
let minutes = comps.last,
let hr = Int(hours),
let min = Int(minutes) else { return 0 }
return hr * 3600 + min * 60
}
let dateString = "2018-04-18T04:54:00-04:00"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssxxxxx"
formatter.locale = Locale(identifier: "en_US_POSIX")
if let dateFromString = formatter.date(from: dateString) {
formatter.timeZone = TimeZone(secondsFromGMT: secondsFromGMT(from: dateString))
formatter.dateFormat = "MMM dd, yyyy 'at' h:mma"
formatter.amSymbol = "am"
formatter.pmSymbol = "pm"
print(formatter.string(from: dateFromString)) // Apr 18, 2018 at 4:54am
}
Anstatt die Date
direkt zu protokollieren, sehen Sie sich die string(from:timeZone:formatOptions:)
-Methode auf ISO8601DateFormatter
an. Damit sollten Sie in der Lage sein, eine Datumszeichenfolge für jede gewünschte Zeitzone zu erhalten.
Sie sollten Ihren Formatierer auf die entsprechende Zeitzone einstellen, z. B. (UTC-Beispiel unten):
formatter.timeZone = TimeZone(identifier: "UTC")
Oder alternativ gegen GMT angeben:
formatter.timeZone = TimeZone(secondsFromGMT: 0)
Das Datum, das Sie von Ihrem aktuellen Formatierer erhalten, ist technisch korrekt. Es wird nicht empfohlen, das Datum wie in der aktuell akzeptierten Antwort beschrieben rückwärts einzustellen, da Sie eine beabsichtigte Zeitzone effektiv hart codieren. Sobald Ihr Gerät eine andere Zeitzone betritt (oder wenn ein Benutzer Ihre App außerhalb der aktuellen Zeitzone herunterlädt), sind Ihre Informationen falsch.
Wenn Sie versuchen, diese Zeit in der UTC-Zeitzone anzuzeigen , müssen Sie einen anderen Formatierer verwenden, um die Ausgabe in der Zielzeitzone korrekt zu formatieren.
let utcFormatter = DateFormatter()
utcFormatter.timeZone = TimeZone(secondsFromGMT: 0)
// Perform any other transformations you'd like
let output = utcFormatter.string(from: date)
Aber warum ist Ihr ursprüngliches Datum korrekt?
Die Date
API ist unglaublich robust und erledigt viele Dinge unter der Haube, wird aber effektiv mit einem einfachen Double
implementiert. Die automatischen Zeitzoneninformationen, die Ihnen angezeigt werden, sind eine Abstraktion, um das Nachdenken zu erleichtern. Ein Datum weiß technisch nicht, in welcher Zeitzone es sich befindet. Wenn Sie es jedoch in eine Zeichenfolge konvertieren, wird implizit ein abgeleiteter Datumsformatierer auf das Datum angewendet und Informationen zurückgegeben, die Ihrer Meinung nach für Sie am nützlichsten sind.
Wenn Sie an einem Datum manipulieren, verwenden Sie wahrscheinlich die Calendar
API. Normalerweise erhalten Sie eine neue Instanz, wenn Sie Calendar.current
verwenden, wodurch ein neuer Kalender mit Ihren aktuellen Zeitzoneninformationen erstellt wird. Sie können die dargestellte Zeitzone des Kalenders folgendermaßen ändern:
var calendar = Calendar.current
calendar.timeZone = TimeZone(secondsFromGMT: 0)
Auf diese Weise erhalten Sie relative Daten, die in jeder Zeitzone funktionieren, ohne das Basisobjekt Date
zu ändern, mit dem Sie arbeiten.
Verwandte Fragen
Neue Fragen
ios
iOS ist das mobile Betriebssystem, das auf dem Apple iPhone, iPod touch und iPad ausgeführt wird. Verwenden Sie dieses Tag [ios] für Fragen zur Programmierung auf der iOS-Plattform. Verwenden Sie die zugehörigen Tags [Objective-C] und [Swift] für Probleme, die für diese Programmiersprachen spezifisch sind.