Achtergrond:Een verrassend veel voorkomende - en grote - misvatting die zelfs door briljante programmeurs wordt gedeeld, is het idee dat opgeslagen tijdstempels (in uw database, Datum, Kalender, Tijdstempel, et al) op de een of andere manier tijdzone-informatie bevatten. Dat doen ze niet. Een tijdstempel (in ieder geval tot Java 8) wordt opgeslagen als het aantal milliseconden sinds middernacht op 1 januari 1970 UTC. Einde van de zin. Het enige dat het instellen van de tijdzone doet, is voldoende informatie aan de computer verstrekken om die tijdstempel om te zetten in een voor mensen leesbaar formaat, en vice versa.
Antwoord:Toen je vermoedde dat dit een tijdzoneprobleem was, je had gelijk . Maar de code die je hebt gebruikt om dit te verifiëren, heeft ook een probleem:
end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));
Dat setTimeZone
verklaring heeft geen effect op de tijd opgeslagen in end
, omdat de tijd al is ingesteld. Het zou alleen effect hebben gehad als je de tijd achteraf had opgeslagen, en dan alleen als je een van de methoden van Calendar had gebruikt die de tijd van een voor mensen leesbaar formaat converteerde (en niet setTimeInMillis
).
Wanneer u getTimeInMillis
gebruikt om de tijdstempel door te geven aan uw voorbereide verklaring, haalt u de tijdstempel rechtstreeks op. Aangezien je het niet naar een menselijk formaat converteert, wordt de tijdzone-informatie opnieuw genegeerd.
Wanneer je probeert
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()));
en
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));
dingen verschijnen om te werken omdat u nu methoden gebruikt die converteren naar/van een voor mensen leesbaar formaat, en daarom wordt de gespecificeerde tijdzone-informatie gebruikt. Dit verbergt echter alleen het echte probleem. Het echte probleem is dat de tijd onjuist werd geconverteerd toen je het ontleden van endString
. Dat wil zeggen, de tijdzone die endString
werd uitgedrukt in komt niet overeen met de tijdzone die is ingesteld in df1
op het moment dat de datum werd geparseerd.
KORT ANTWOORD:voor deze regel:
end.setTime(df1.parse(endString));
U moet:
- Bepaal in welke tijdzone de tijd is in
endString
werd uitgedrukt in. - Stel
df1
in en nietend
naar diezelfde tijdzone. Sindsdf1
is het ding dat de datum converteert van menselijk formaat, het is die tijdzone-informatie die wordt gebruikt.
Proost!