Предистория:Изненадващо често срещано – и голямо – погрешно схващане, споделяно дори от брилянтни програмисти, е идеята, че съхранените времеви печати (във вашата база данни, дата, календар, времеви отпечатъци и др.) по някакъв начин имат информация за часовата зона. Не го правят. Печат за време (все пак до Java 8) се съхранява като брой милисекунди от полунощ на 1 януари 1970 г. UTC. Край на изречението. Единственото нещо, което прави настройката на часовата зона, е да предостави достатъчно информация на компютъра, за да преобразува това времеви печат в четим от човека формат и обратно.
Отговор:Когато подозирахте, че това е проблем с часовата зона, бяхте прав . Но кодът, който сте използвали, за да потвърдите това, също има проблем:
end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));
Това setTimeZone
изявлението няма ефект във времето, съхранено в end
, защото часът вече е зададен. Това би имало ефект само ако сте съхранили времето след това и след това само ако сте използвали един от методите на Calendar, който преобразува времето от формат, четим от човека (а не setTimeInMillis
).
Когато използвате getTimeInMillis
за да предадете времевия печат на подготвеното изявление, вие извличате директно времевия печат. Тъй като не го конвертирате в човешки формат, отново информацията за часовата зона се игнорира.
Когато опитате
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()));
и
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));
нещатапоявяват да работи, защото сега използвате методи, които преобразуват в/от четим от човека формат и следователно се използва определената информация за часовата зона. Това обаче само прикрива истинския проблем. Истинският проблем е, че времето е било неправилно преобразувано, когато сте го анализирали от endString
. Тоест часовата зона, която endString
е изразен в не съответства на часовата зона, зададена в df1
в момента на анализиране на датата.
КРАТЪК ОТГОВОР:преди този ред:
end.setTime(df1.parse(endString));
Трябва да:
- Определете в коя часова зона е часът в
endString
беше изразено в. - Задайте
df1
инеend
към същата часова зона. Тъй катоdf1
е нещото, което преобразува датата от човешки формат, това е информацията за часовата зона, която се използва.
Наздраве!