2011-06-22 30 views
9
Date nowdate = new Date(); 
long nowms = nowdate.getTime(); 
long differencems = numdaysback * 24 * 60 * 60 * 1000; 
long thenms = nowms - differencems; 
Date thendate = new Date(thenms); 

Nếu numdaysback là 365, thì tôi giả sử rằng thendate sẽ là một năm trước. nhưng nó không ... nó khoảng ba tuần trước?!?Các sự cố về Java ngày, tìm ngày X ngày trước

NUMDAYSBACK: 365 
NOWDATE: Wed Jun 22 20:31:58 SGT 2011 
NOWMS: 1308745918625 
DIFFERENCEMS: 1471228928 
THENMS: 1307274689697 
THENDATE: Sun Jun 05 19:51:29 SGT 2011 

Trả lời

25

Làm thế nào về:

Calendar cal = Calendar.getInstance(); 
cal.add(Calendar.YEAR, -1); 
Date thendate = cal.getTime(); 

Trả lại thời của ngày bất kể DST hay năm nhuận, là ngắn hơn và rõ ràng hơn ...

chung Calendar là con đường để đi trong ví dụ trường hợp (trừ khi bạn sử dụng thư viện của bên thứ ba như Joda Time). Bạn có thể sử dụng nó cho tất cả các loại tính toán: thêm N ngày/giờ/tháng/giây, cắt ngắn thời gian cho cả một giờ, v.v. - những thứ quá đau đớn chỉ với long.

Về câu hỏi ban đầu của bạn, có vẻ như đó là nạn nhân của tràn số nguyên. Nó hoạt động nếu nhân một cách rõ ràng sử dụng dài:

long differencems = 365 * 24 * 60 * 60 * 1000L; 
+0

Giải pháp tốt. Bây giờ tất cả đều hoạt động như dự định :) – Jesper

+3

+1 để nói cho anh ta biết điều gì sai, thay vì chỉ đơn giản là đưa ra giải pháp. –

0

dòng này:

long differencems = numdaysback * 24 * 60 * 60 * 1000; 

RHS nên là: 31536000000. Bạn có một cái gì đó ít hơn nhiều, lý do là RHS đang được đánh giá là một int (vì tất cả số lượng là int) và bạn vượt quá MAX_INT. Để sửa lại điều này:

long differencems = numdaysback * 24 * 60 * 60 * 1000l; 

Lưu ý "l" làm cho 1000 trở thành dài - bây giờ RHS sẽ được đánh giá là dài.

+0

Nhờ tất cả mọi người ở đây. Tôi sẽ đi với lịch như bạn sẽ đề nghị. – Jesper

3

Chỉ cần cố gắng này:

long differencems = numdaysback * 24L * 60 * 60 * 1000; 

Với mã mới, bạn sẽ không mất các chữ số do số nguyên nhân. Vì chúng ta đã đánh dấu chữ cái là 24, nên phép nhân sẽ được thực hiện bằng cách tự động chuyển đổi toán hạng đầu tiên thành số nguyên. Phần còn lại của phép nhân cũng sẽ được thực hiện trên các toán hạng dài.

0

Lớp học Date không được chấp nhận. API có rất nhiều lỗi, thật khó để có được Dates/Times ngay với nó. Ví dụ đơn giản nhất giống như mã của bạn cho differencems. Nó không thành công, nếu time inbetween chứa một công tắc tiết kiệm ánh sáng ban ngày (nếu bạn không sử dụng UT) và sẽ luôn thất bại trong việc xử lý các giây nhảy vọt.

Nếu đơn đăng ký của bạn tùy thuộc vào ngày chính xác, bạn có thể muốn sử dụng Joda Time.

Các vấn đề liên quan