Baggrund:En overraskende almindelig – og stor – misforståelse, som deles af selv geniale programmører, er forestillingen om, at gemte tidsstempler (i din database, Dato, Kalender, Tidsstempel, et al.) på en eller anden måde har tidszoneoplysninger. Det gør de ikke. Et tidsstempel (i hvert fald indtil Java 8) gemmes som antallet af millisekunder siden midnat den 1. januar 1970 UTC. Slut på sætning. Det eneste, som indstiller tidszonen, er at give computeren nok information til at konvertere tidsstemplet til et format, der kan læses af mennesker, og omvendt.
Svar:Da du havde mistanke om, at dette var et tidszoneproblem, har du ret . Men koden du brugte til at prøve at bekræfte dette har også et problem:
end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));
Det setTimeZone
erklæring har ingen effekt på det tidspunkt, der er gemt i end
, fordi tiden allerede er indstillet. Det ville kun have haft en effekt, hvis du gemte tiden bagefter, og så kun hvis du brugte en af Kalenders metoder, som konverterede tiden fra et menneskeligt læsbart format (og ikke setTimeInMillis
).
Når du bruger getTimeInMillis
for at videregive tidsstemplet til din udarbejdede erklæring, henter du tidsstemplet direkte. Da du ikke konverterer det til et menneskeligt format, ignoreres tidszoneinformationen igen.
Når du prøver
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()));
og
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));
ting vises til at virke, fordi du nu bruger metoder, der konverterer til/fra et menneskeligt læsbart format, og derfor bruges den angivne tidszoneinformation. Dette dækker dog kun over det egentlige problem. Det virkelige problem er, at klokkeslættet blev konverteret forkert, da du analyserede det fra endString
. Det vil sige den tidszone, som endString
blev udtrykt i, stemmer ikke overens med tidszonen indstillet i df1
på det tidspunkt, hvor datoen blev parset.
KORT SVAR:før denne linje:
end.setTime(df1.parse(endString));
Du skal:
- Find ud af, hvilken tidszone tiden er i
endString
kom til udtryk i. - Indstil
df1
og ikkeend
til samme tidszone. Sidendf1
er det, der konverterer datoen fra et menneskeligt format, det er den tidszoneinformation, der bruges.
Skål!