Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Rozbieżność strefy czasowej w mysql i java

Tło:Zaskakująco powszechnym – i dużym – błędnym przekonaniem podzielanym przez nawet błyskotliwych programistów jest pogląd, że przechowywane znaczniki czasu (w twojej bazie danych, data, kalendarz, znacznik czasu itp.) w jakiś sposób zawierają informacje o strefie czasowej. Nie. Znacznik czasu (w każdym razie do wersji Java 8) jest przechowywany jako liczba milisekund od północy 1 stycznia 1970 UTC. Koniec zdania. Jedyne, co ustawia strefę czasową, to dostarczenie komputerowi wystarczającej ilości informacji, aby przekonwertować ten znacznik czasu na format czytelny dla człowieka i odwrotnie.

Odpowiedź:Kiedy podejrzewałeś, że to problem ze strefą czasową, miałeś rację . Ale kod, którego użyłeś, aby to zweryfikować, również ma problem:

end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));

Ten setTimeZone oświadczenie nie ma wpływu o czasie zapisanym w end , bo czas został już ustawiony. Miałoby to efekt tylko wtedy, gdybyś zapisał czas później, i tylko wtedy, gdybyś użył jednej z metod Kalendarza, która konwertowała czas z formatu czytelnego dla człowieka (a nie setTimeInMillis ).

Kiedy używasz getTimeInMillis aby przekazać znacznik czasu do przygotowanego wyciągu, pobierasz bezpośrednio znacznik czasu. Ponieważ nie konwertujesz go do formatu ludzkiego, ponownie informacje o strefie czasowej są ignorowane.

Kiedy spróbujesz

SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
end.setTime(sdf.parse("2012-10-01 00:00:00"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTime()));

i

pst.setTimestamp(1, new java.sql.Timestamp(octDate.get(Calendar.YEAR)-1900,octDate.get(Calendar.MONTH),octDate.get(Calendar.DATE),octDate.get(Calendar.HOUR),octDate.get(Calendar.MINUTE),octDate.get(Calendar.SECOND),0));
pst.setTimestamp(2, new java.sql.Timestamp(end.get(Calendar.YEAR)-1900,end.get(Calendar.MONTH),end.get(Calendar.DATE),end.get(Calendar.HOUR),end.get(Calendar.MINUTE),end.get(Calendar.SECOND),0));

rzeczy pojawiają się do pracy, ponieważ używasz teraz metod, które konwertują do/z formatu czytelnego dla człowieka, a zatem używane są informacje o określonej strefie czasowej. Jednak to tylko ukrywa prawdziwy problem. Prawdziwym problemem jest to, że czas został nieprawidłowo przekonwertowany podczas analizowania go z endString . Oznacza to, że strefa czasowa endString został wyrażony w nie pasuje do strefy czasowej ustawionej w df1 w momencie analizowania daty.

KRÓTKA ODPOWIEDŹ:przed tą linią:

end.setTime(df1.parse(endString));

Musisz:

  • Dowiedz się, w jakiej strefie czasowej czas w endString został wyrażony w.
  • Ustaw df1 i nie end do tej samej strefy czasowej. Od df1 to rzecz, która konwertuje datę z formatu ludzkiego, to ta informacja o strefie czasowej jest używana.

Pozdrawiam!



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak podłączyć mysql workbench do uruchamiania mysql w dockerze?

  2. Jak używać jQuery SlickGrid z PHP / MySQL (załaduj dane serwera i zapisz zmiany)

  3. Konwertuj obiekt na ciąg w PHP

  4. Wstawka MySQL przy zduplikowanej aktualizacji dla klucza innego niż PODSTAWOWY

  5. Znajomy znajomego w PHP/MySQL?