Pozadí:Překvapivě běžnou – a velkou – mylnou představou, kterou sdílejí i brilantní programátoři, je představa, že uložená časová razítka (ve vaší databázi, Datum, Kalendář, Časové razítko atd.) nějakým způsobem obsahují informace o časovém pásmu. Nedělají. Časová známka (až do Java 8) je uložena jako počet milisekund od půlnoci 1. ledna 1970 UTC. Konec věty. Jediná věc, kterou nastavení časového pásma dělá, je poskytnout počítači dostatek informací k převedení časového razítka do formátu čitelného člověkem a naopak.
Odpověď:Když jste měli podezření, že se jedná o problém s časovým pásmem, měli jste pravdu . Ale kód, který jste použili k ověření, má také problém:
end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));
To setTimeZone
prohlášení nemá žádný účinek v čase uloženém v end
, protože čas již byl nastaven. Účinek by to mělo pouze tehdy, pokud byste čas uložili později, a to pouze tehdy, pokud byste použili jednu z metod Kalendáře, která převedla čas z formátu čitelného člověkem (a nikoli setTimeInMillis
).
Když použijete getTimeInMillis
pro předání časového razítka do připraveného výpisu získáváte časové razítko přímo. Protože jej nepřevádíte do lidského formátu, informace o časovém pásmu jsou opět ignorovány.
Když to zkusíte
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()));
a
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));
věci se objevují fungovat, protože nyní používáte metody, které převádějí do/z formátu čitelného člověkem, a proto se používají zadané informace o časovém pásmu. To však pouze zakrývá skutečný problém. Skutečným problémem je, že čas byl nesprávně převeden, když jste jej analyzovali z endString
. Tedy časové pásmo, které endString
byl vyjádřen v neodpovídá časovému pásmu nastavenému v df1
v době, kdy bylo datum analyzováno.
KRÁTKÁ ODPOVĚĎ:před tímto řádkem:
end.setTime(df1.parse(endString));
Musíte:
- Zjistěte, v jakém časovém pásmu je čas v
endString
byl vyjádřen v. - Nastavte
df1
a neend
do stejného časového pásma. Oddf1
je věc, která převádí datum z lidského formátu, jsou to informace o časovém pásmu, které se používají.
Na zdraví!