„Coders hate dates” czyli kilka podstawowych informacji o przetwarzaniu dat w Javie oraz przechowywaniu ich w bazie Oracle. Aby przetwarzanie informacji o czasie poszło nam sprawnie i bez przykrych niespodzianek należy pamiętać o kilku sprawach:

  • java.sql.Date nie zawiera informacji o czasie (przy tworzeniu obiektu tej klasy z java.util.Date informacje o czasie są ustawiane na 00:00), tak więc aby zapisać takie informacje należy użyć java.sql.Timestamp. Aczkolwiek typ bazodanowy „DATE” zawiera już informacje o czasie.
  • Typy „DATE” oraz „TIMESTAMP” nie zawierają informacji o strefie czasowej. Aby zawrzeć takie informacje, należy użyć typu „TIMESTAMP WITH TIME ZONE” lub „TIMESTAMP WITH LOCAL TIME ZONE„.
  • Sterownik JDBC ma błąd, który powoduje iż przy zapisie zawsze(niezależnie od przekazanych informacji do zapytania) ustawiana jest aktualna strefa czasowa sesji Oracle:
SELECT sessiontimezone FROM DUAL;
  • Nie ma możliwości odczytania bezpośrednio wszystkich informacji z „TIMESTAMP WITH TIME ZONE„, pozostaje tylko parsowanie stringa. Ciekawe rozwiązanie przedstawiono tutaj.
  • Nie można zmienić strefy czasowej ustawionej w bazie Oracle, jeśli w naszej bazie mamy tabele z kolumną typu „TIMESTAMP WITH LOCAL TIME ZONE„. ORA-30079

Uzbrojony w taką wiedzę zdecydowałem się w swoim rozwiązaniu przechowywać informacje o czasie po prostu w kolumnie typu „TIMESTAMP„, zakładając że będę tam zawsze składował czas w UTC. Natomiast wszelkie operacje konwersji pomiędzy strefami czasowymi będą obsługiwane przez aplikację. Do tego typu zabaw polecam bibliotekę Joda-Time, w której znajdziemy wszystko co nam potrzeba przy obliczeniach związanych z czasem. Oczywiście powstało kilka implementacji Joda-Time na GWT np. gwt-time. Miłej zabawy 😉