Bakgrund:En förvånansvärt vanlig – och stor – missuppfattning som delas av även briljanta programmerare är uppfattningen att lagrade tidsstämplar (i din databas, Datum, Kalender, Tidstämpel, et al) på något sätt har tidszoninformation. Det gör de inte. En tidsstämpel (fram till Java 8 i alla fall) lagras som antalet millisekunder sedan midnatt den 1 januari 1970 UTC. Slutet på meningen. Det enda som ställer in tidszonen är att tillhandahålla tillräckligt med information till datorn för att konvertera den tidsstämpeln till ett läsbart format, och vice versa.
Svar:När du misstänkte att detta var ett tidszonproblem, har du rätt . Men koden du använde för att verifiera detta har också ett problem:
end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));
Den där setTimeZone
uttalandet har ingen effekt på tiden som är lagrad i end
, eftersom tiden redan är inställd. Det hade bara haft effekt om du lagrade tiden efteråt, och då bara om du använde någon av Kalenders metoder som konverterade tiden från ett mänskligt läsbart format (och inte setTimeInMillis
).
När du använder getTimeInMillis
för att skicka tidsstämpeln till ditt förberedda utdrag, hämtar du tidsstämpeln direkt. Eftersom du inte konverterar det till ett mänskligt format, ignoreras återigen tidszonsinformationen.
När du försöker
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()));
och
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));
saker visas att fungera eftersom du nu använder metoder som konverterar till/från ett mänskligt läsbart format, och därför används den angivna tidszonsinformationen. Detta döljer dock bara det verkliga problemet. Det verkliga problemet är att tiden konverterades felaktigt när du analyserade den från endString
. Det vill säga tidszonen som endString
uttrycktes i stämmer inte överens med tidszonen i df1
vid den tidpunkt då datumet analyserades.
KORT SVAR:före denna rad:
end.setTime(df1.parse(endString));
Du måste:
- Ta reda på vilken tidszon tiden är i
endString
uttrycktes i. - Ställ in
df1
och inteend
till samma tidszon. Sedandf1
är det som konverterar datumet från mänskligt format, det är den tidszonsinformationen som används.
Skål!