Cơ sở:Một quan niệm sai lầm phổ biến đáng ngạc nhiên - và lớn - được chia sẻ bởi ngay cả những lập trình viên xuất sắc là quan điểm cho rằng dấu thời gian được lưu trữ (trong cơ sở dữ liệu của bạn, Ngày, Lịch, Dấu thời gian, v.v.) bằng cách nào đó có thông tin múi giờ. Họ không. Dấu thời gian (dù sao cũng cho đến Java 8) được lưu trữ dưới dạng số mili giây kể từ nửa đêm ngày 1 tháng 1 năm 1970 theo giờ UTC. Cuối câu. Điều duy nhất mà thiết lập múi giờ làm là cung cấp đủ thông tin cho máy tính để chuyển đổi dấu thời gian đó sang định dạng con người có thể đọc được và ngược lại.
Trả lời:Khi bạn nghi ngờ rằng đây là vấn đề về múi giờ, bạn đã đúng . Nhưng mã bạn đã sử dụng để cố gắng xác minh điều này cũng có vấn đề:
end.setTimeZone(TimeZone.getTimeZone("America/New York"));
pst.setTimestamp(1, new java.sql.Timestamp(end.getTimeInMillis()));
setTimeZone
đó tuyên bố không có hiệu lực vào thời gian được lưu trữ trong end
, bởi vì thời gian đã được thiết lập. Nó sẽ chỉ có hiệu lực nếu bạn lưu trữ thời gian sau đó, và sau đó chỉ khi bạn sử dụng một trong các phương pháp của Lịch để chuyển đổi thời gian từ định dạng con người có thể đọc được (chứ không phải setTimeInMillis
).
Khi bạn sử dụng getTimeInMillis
để chuyển dấu thời gian vào bảng sao kê đã chuẩn bị của bạn, bạn đang truy xuất trực tiếp dấu thời gian. Vì bạn không chuyển đổi nó sang định dạng người, một lần nữa thông tin múi giờ bị bỏ qua.
Khi bạn thử
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()));
và
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));
những thứ xuất hiện để hoạt động vì bạn hiện đang sử dụng các phương thức chuyển đổi sang / từ định dạng con người có thể đọc được, và do đó thông tin múi giờ đã chỉ định được sử dụng. Tuy nhiên, điều này chỉ đang che đậy vấn đề thực sự. Vấn đề thực sự là thời gian đã được chuyển đổi không đúng cách khi bạn phân tích cú pháp từ endString
. Đó là, múi giờ mà endString
được biểu thị bằng không khớp với múi giờ được đặt trong df1
tại thời điểm ngày được phân tích cú pháp.
TRẢ LỜI NGẮN:trước dòng này:
end.setTime(df1.parse(endString));
Bạn cần:
- Tìm ra múi giờ múi giờ trong
endString
được thể hiện trong. - Đặt
df1
và khôngend
đến cùng múi giờ đó. Kể từdf1
là thứ đang chuyển đổi ngày từ định dạng con người, đó là thông tin múi giờ được sử dụng.
Chúc mừng!