Gut Sie eine Lösung gefunden, würde ich nur Ich möchte einige Einsichten hinzufügen und eine kleine Verbesserung für your answer vorschlagen.
Das Festlegen der JVM-Standardzeitzone mit TimeZone.setDefault
ist nicht der beste Weg, dies zu erreichen. Obwohl es für die meisten Zeiten funktioniert, ist es ein wenig riskant und fehleranfällig, wenn Sie bedenken, dass dieser Code in einer komplexeren Umgebung ausgeführt wird.
Das ist, weil TimeZone.setDefault
die Standardzeitzone für die ganze JVM ändert. Jede andere Anwendung, die in derselben JVM ausgeführt wird, wird davon betroffen sein. Andere Teile derselben Anwendung sind ebenfalls betroffen, und selbst derselbe Code, der in mehreren Threads ausgeführt wird, kann zu falschen Ergebnissen führen (und race conditions are hard to debug).
Ich habe festgestellt, dass Sie TimeZone.setDefault(TimeZone.getTimeZone(timezone));
verwenden. Dies bedeutet, dass Sie bereits mit einer bestimmten Zeitzone arbeiten, sodass Sie sich nicht auf die Standardeinstellung der JVM verlassen müssen. Wenn Sie einen bestimmten Zeitzonennamen haben, verwenden Sie diesen anstelle des Standardnamens. So empfehle ich Ihnen, dass die addDays
Methode wie folgt sein sollte:
public ZonedDateTime addDays(long myUTCTimeInSeconds, int days, String timezone) {
// get the instant from the UTC seconds
Instant instant = Instant.ofEpochSecond(myUTCTimeInSeconds);
// get the instant at the specified timezone
ZonedDateTime z = instant.atZone(ZoneId.of(timezone));
// add days
return z.plusDays(days);
}
Die Verbesserungen vorgenommen:
plusDays
bereits 1 Tag subtrahiert, wenn Sie -1
es passieren. Sie müssen den Wert nicht überprüfen und die Methode abs
verwenden.
- verwenden die JVM Standard-Zeitzone nicht: statt
ZoneId.systemDefault()
, verwenden Sie die timezone
, die Sie bereits haben (die Sie in der setDefault
Methode wurden)
instant.atZone
ist ZonedDateTime.ofInstant
gleichwertig.IMO, atZone
ist mehr "lesbar", aber in diesem Fall ist es eine Frage der Wahl und Code-Stil. Es macht keinen Unterschied im Endergebnis.
Damit könnten Sie tun:
// call directly, no need to change the default timezone
System.out.println(addDays(1459123200, -1, "Europe/Stockholm"));
Dieser Druck wird:
2016-03-27T03: 00 + 02: 00 [Europa/Stockholm]
Sie können einen Tag nicht von einem * lokalen * Datum/Uhrzeit, das keine Sommerzeiteinsparungen erwartet, subtrahieren und erwarten, dass Sommerzeit-Regeln angewendet werden. – RealSkeptic
@RealSkeptic Können Sie vorschlagen, wie Sie es schaffen? –
Wenn Sie Datum/Uhrzeit in Zonen einteilen möchten, verwenden Sie "ZonedDateTime". Verwenden Sie nicht 'LocalDateTime'. – RealSkeptic