Solange es Java gibt, waren java.util.Date und java.util.Calendar ein Ärgernis. Mit der Erweiterung der Java-API um JSR-310, die Date and Time API, wird dies hoffentlich bald der Vergangenheit angehören. Die Grundlage von JSR-310 bildet die Joda-Zeitbibliothek, die schon seit einiger Zeit als Ersatz für die Standardklassen Date und Calendar existiert. Dass diese API jedoch nicht ohne ihre Eigenheiten ist, muss angesichts der Komplexität der menschlichen Interpretation der Zeit auf der ganzen Welt nicht überraschen.
In unserem aktuellen Projekt haben wir einen Wert in der Datenbank, der einen Zeitstempel in der Zeitzone UTC oder "Zulu" enthält. Dieser Zeitstempel wird mit einer java.sql.Timestamp-Instanz aus der Datenbank geholt. Unsere Anwendung arbeitet jedoch mit org.joda.time.DateTime-Instanzen in der lokalen Zeitzone, die für die Niederlande entweder CET (UTC+0100) oder CEST (UTC+0200) ist, abhängig von der Sommerzeit. Unser Problem besteht also darin, einen UTC java.sql.Timestamp in einen org.joda.time.DateTime in der richtigen Zeitzone zu konvertieren, der die richtige Zeit darstellt. Beginnen wir mit dem Schreiben eines kleinen JUnit-Skelett-Tests:
public class DateTimePainsTest extends TestCase {
private static final String WRONG_TIME = "2008-03-26T20:13:39.059+01:00";
private static final String CORRECT_TIME = "2008-03-26T21:13:39.059+01:00";
private long millis;
private Zeitstempel timestamp;
protected void setUp() throws Exception {
millis = new Date(1206558819059L).getTime(); // 2008-03-26T20:13:39.059+00:00
timestamp = new Timestamp(millis);
}
public void testMillisAndTimestamp() {
assertEquals(millis, timestamp.getTime());
assertEquals("2008-03-26 20:13:39.059", timestamp.toString());
}
}
Nun möchten wir diesen Zeitstempel in ein DateTime-Objekt konvertieren, das die folgende Zeichenkette darstellt: 2008-03-26T21:13:39.059+01:00. Wir versuchen zunächst die einfachste Option, die uns einfällt:
public void testDateTimeConversion1() {
DateTime dateTime = new DateTime(timestamp.getTime(),
DateTimeZone.forOffsetHours(1));
assertEquals(CORRECT_TIME, dateTime.toString());
}
Dieser Test schlägt fehl. Damit der Test erfolgreich ist, müssen wir WRONG_TIME darin erwarten. Obwohl dies laut der JavaDoc von DateTime ein Schritt in die richtige Richtung sein sollte:
DateTime(long instant, DateTimeZone zone)
Constructs an instance set to the milliseconds from 1970-01-01T00:00:00Z using ISOChronology in the specified time zone.
Vielleicht sollten wir zuerst die Zeitzone UTC erzwingen, bevor wir die DateTime in eine europäische Zeitzone konvertieren. Versuchen wir das mal:
public void testDateTimeConversion2() {
DateTime dateTime = new DateTime(timestamp.getTime(), DateTimeZone.UTC)
.withZone(DateTimeZone.forOffsetHours(1));
assertEquals(CORRECT_TIME, dateTime.toString());
}
Auch dieser Test schlägt fehl. Wenn Sie WRONG_TIME durch CORRECT_TIME ersetzen, erhalten Sie zwar einen grünen Balken, aber ein unerwünschtes Ergebnis, so dass wir einen anderen Ansatz wählen sollten. LocalDateTime ist eine Joda-Zeitklasse, die keine Zeitzoneninformationen berücksichtigt. Vielleicht können wir diese in eine DateTime in der richtigen Zeitzone umwandeln. Lassen Sie uns einen neuen Testfall schreiben:
public void testDateTimeConversion3() {
DateTime dateTime = new LocalDateTime(Zeitstempel)
.toDateTime(DateTimeZone.forOffsetHours(1));
assertEquals(CORRECT_TIME, dateTime.toString());
}
Auch dieser Test schlägt fehl. Wir müssen die WRONG_TIME erwarten, um einen grünen Balken zu erhalten. Der Trick scheint zu sein, die LocalDateTime in eine DateTime in der UTC-Zeitzone zu konvertieren und dieser dann die richtige Zeitzone zuzuweisen. Und siehe da, der folgende Testfall funktioniert:
public void testDateTimeConversion4() {
DateTime try3 = new LocalDateTime(timestamp).toDateTime(DateTimeZone.UTC)
.withZone(DateTimeZone.forOffsetHours(1));
assertEquals(CORRECT_TIME, try3.toString());
}
Diese Lösung funktioniert zwar, ist aber meiner Meinung nach nicht die optimale Lösung. Kennt jemand eine bessere Lösung? Wenn ja, geben Sie bitte einen Kommentar ab.
Verfasst von

Jeroen van Erp
Unsere Ideen
Weitere Blogs
Contact



