2010-04-13 14 views
66

Potrzebuję wymuszać w dowolnym czasie powiązane operacje z GMT/UTC, niezależnie od strefy czasowej ustawionej na komputerze. Dowolny wygodny sposób w kodzie?Wymuś strefę czasową Java jako GMT/UTC

Aby wyjaśnić, używam czasu serwera bazy danych dla wszystkich operacji, ale jest on sformatowany zgodnie z lokalną strefą czasową.

Dzięki!

+0

W rzeczywistości jego problem jest moim podzbiorem, ale znalazłem rozwiązanie. – SyBer

+0

Sprawdź powielone pytanie i wyszukaj "Joda" i "DateTimeZone". –

Odpowiedz

90

PO odpowiedział na to pytanie, aby zmienić domyślną strefę czasową dla pojedynczej instancji uruchomionego JVM, należy ustawić właściwość systemu user.timezone:

java -Duser.timezone=GMT ... <main-class> 

Jeśli trzeba ustawić określone strefy czasowe podczas pobierania obiektów Date/Time/Timestamp z bazy danych ResultSet, użyj drugiej metody getXXX, która wymaga obiektu Calendar:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
ResultSet rs = ...; 
while (rs.next()) { 
    Date dateValue = rs.getDate("DateColumn", tzCal); 
    // Other fields and calculations 
} 

Albo, wyznaczając datę w PreparedStatement:

Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); 
PreparedStatement ps = conn.createPreparedStatement("update ..."); 
ps.setDate("DateColumn", dateValue, tzCal); 
// Other assignments 
ps.executeUpdate(); 

To zapewni, że wartość przechowywana w bazie danych jest spójna, gdy kolumna w bazie nie przechowuje strefy czasowej.

Klasy java.util.Date i java.sql.Date przechowują rzeczywisty czas (milisekundy) w UTC. Aby sformatować je na wyjściu do innej strefy czasowej, użyj SimpleDateFormat. Można także powiązać z wartością czasową za pomocą obiektu Kalendarz:

TimeZone tz = TimeZone.getTimeZone("<local-time-zone>"); 
//... 
Date dateValue = rs.getDate("DateColumn"); 
Calendar calValue = Calendar.getInstance(tz); 
calValue.setTime(dateValue); 
+0

Jedną z rzeczy, o których warto pamiętać, aby ustawić strefę czasową dla całej maszyny JVM, jest to, że wpływa ona na wszystko, w tym na takie operacje, jak rejestrowanie. Po prostu coś, o czym należy pamiętać, jeśli jest to pożądany efekt. –

+0

Tak, w porządku. Tylko jeden punkt, aby wspomnieć, że faktycznie ustawić user.timezone bezpośrednio w kodzie, a następnie za pośrednictwem parametru -D. – SyBer

+5

@SyBer: To działa, ale musisz upewnić się, że ustawiłeś to zanim jakakolwiek metoda wywoła metodę TimeZone.getDefault(). Jeśli nie, będziesz mieć pewne zamieszanie, ponieważ domyślna wartość jest buforowana po pierwszym wykonaniu. Oznacza to również, że może to stanowić problem, jeśli robisz to w interfejsie API/bibliotece (ukryty przed zwykłym widokiem) - pamiętaj, aby udokumentować, co robisz. –

6

Chciałbym pobrać czas z DB w surowej postaci (długi datownik lub Data Java), a następnie użyć SimpleDateFormat do sformatowania lub kalendarza do manipulowania nim. W obu przypadkach należy ustawić strefę czasową obiektów przed użyciem.

Zobacz SimpleDateFormat.setTimeZone(..) i Calendar.setTimeZone(..) szczegóły

3

Można zmienić strefę czasową korzystając TimeZone.setDefault() - nawet tylko tymczasowo, dla niektórych operacji.

+0

Bez urazy, ale chwilowa modyfikacja globalnego statycznego stanu brzmi jak bardzo zły pomysł ... –

12

Także jeśli można ustawić strefę czasową JVM ten sposób

System.setProperty("user.timezone", "EST"); 

lub -Duser.timezone=GMT w args JVM.

7

dla mnie, po prostu szybkie SimpleDateFormat,

private static final SimpleDateFormat GMT = new SimpleDateFormat("yyyy-MM-dd"); 
    private static final SimpleDateFormat SYD = new SimpleDateFormat("yyyy-MM-dd"); 
    static { 
     GMT.setTimeZone(TimeZone.getTimeZone("GMT")); 
    SYD.setTimeZone(TimeZone.getTimeZone("Australia/Sydney")); 
    } 

następnie sformatować datę z innej strefy czasowej.

1

utworzyć parę klient/serwer, aby po wykonaniu serwer klienta wysłał prawidłową godzinę i datę. Następnie klient prosi serwer pm GMT, a serwer odsyła odpowiedź właściwą.

-2

Jeśli chcesz uzyskać czas GMT tylko z intigerem: var currentTime = new Date(); var currentYear = '2010' var currentMonth = 10; var CURRENTDAY = '30' var currentHours = '20' var currentMinutes = '20' var currentSeconds = '00' var currentMilliseconds = 00'

currentTime.setFullYear(currentYear); 
currentTime.setMonth((currentMonth-1)); //0is January 
currentTime.setDate(currentDay); 
currentTime.setHours(currentHours); 
currentTime.setMinutes(currentMinutes); 
currentTime.setSeconds(currentSeconds); 
currentTime.setMilliseconds(currentMilliseconds); 

var currentTimezone = currentTime.getTimezoneOffset(); 
currentTimezone = (currentTimezone/60) * -1; 
var gmt =""; 
if (currentTimezone !== 0) { 
    gmt += currentTimezone > 0 ? ' +' : ' '; 
    gmt += currentTimezone; 
} 
alert(gmt) 
+2

który wygląda mi na JavaScript (! = Java). – Phil

1

wow. Wiem, że jest to starożytny wątek, ale wszystko, co mogę powiedzieć, to nie wywoływać TimeZone.setDefault() w żadnym kodzie poziomu użytkownika. To zawsze ustawia Strefę czasową dla całej maszyny JVM i jest prawie zawsze bardzo złym pomysłem. Naucz się korzystać z biblioteki joda.time lub nowej klasy DateTime w Javie 8, która jest bardzo podobna do biblioteki joda.time.