2011-09-23 36 views
14
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/New_York")); 
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); 
df.setTimeZone(TimeZone.getTimeZone("America/New_York")); 

try { 
    System.out.println(df.format(cal.getTime())); 
    System.out.println(df.parse(df.format(cal.getTime()))); 
} catch (ParseException e) { 
    e.printStackTrace(); 
} 

Dưới đây là kết quả:Java DateFormat parse() không tôn trọng các múi giờ

2011-09-24 14:10:51 -0400

Sat 24 tháng 9 20:10 : 51 CEST 2011

Tại sao khi tôi phân tích ngày tôi nhận được từ định dạng() nó không tôn trọng múi giờ?

Trả lời

23

Bạn đang in kết quả gọi Date.toString(), trong đó luôn luôn sử dụng múi giờ mặc định. Về cơ bản, bạn không nên sử dụng Date.toString() cho bất kỳ điều gì khác ngoài gỡ lỗi.

Đừng quên rằng Date không múi giờ - nó thể hiện ngay lập tức, được tính bằng mili giây kể từ kỷ nguyên Unix (nửa đêm ngày 1 tháng 1 năm 1970 UTC).

Nếu bạn định dạng ngày bằng cách sử dụng trình định dạng lại, rằng sẽ đưa ra câu trả lời giống như trước đây.

Ngoài ra, tôi khuyên bạn nên sử dụng Joda Time thay vì Date/Calendar nếu bạn đang thực hiện bất kỳ số lượng ngày/giờ đáng kể nào trong Java; đó là nhiều hơn API đẹp hơn.

+1

Đúng vậy ... thử in 'System.out.println (df.format (df.parse (df.format (cal.getTime())))); 'và nó hoạt động như mong đợi :-) –

+0

Ok vì vậy dường như vấn đề xuất phát từ toString()? Cảm ơn vì lời khuyên. –

+0

@MaximeLaval: Từ 'Date.toString' nói riêng, có - và bạn cần phải biết rằng' Date' chỉ là một khoảnh khắc, không nằm trong bất kỳ múi giờ hoặc lịch cụ thể nào. –

2

DateFormat là lớp trừu tượng cho các lớp con định dạng ngày/giờ định dạng và phân tích ngày hoặc giờ theo cách độc lập theo ngôn ngữ . Lớp con định dạng ngày/giờ, chẳng hạn như SimpleDateFormat, cho phép định dạng (ví dụ: ngày -> văn bản), phân tích cú pháp (văn bản -> ngày), và chuẩn hóa. Ngày được biểu thị dưới dạng đối tượng Ngày hoặc dưới dạng mili giây kể từ ngày 1 tháng 1 năm 1970, 00:00:00 GMT.

Từ spec, nó trở EPOCH thời gian

7

DateFormat.parse() KHÔNG phải là một truy vấn (cái gì mà trả về giá trị và không thay đổi trạng thái của hệ thống). Nó là một lệnh có tác dụng phụ khi cập nhật đối tượng Calendar bên trong. Sau khi gọi số parse(), bạn phải truy cập múi giờ bằng cách truy cập vào số Calendar của DateFormat hoặc gọi DateFormat.getTimeZone(). Trừ khi bạn muốn vứt bỏ múi giờ ban đầu và sử dụng giờ địa phương, không sử dụng giá trị Date trả lại từ parse(). Thay vào đó hãy sử dụng đối tượng lịch sau khi phân tích cú pháp. Và điều này cũng đúng cho phương pháp định dạng. Nếu bạn định định dạng ngày, hãy chuyển lịch với thông tin múi giờ vào đối tượng DateFormat trước khi gọi format(). Đây là cách bạn có thể chuyển đổi một định dạng sang định dạng khác giữ gìn múi giờ gốc:

DateFormat originalDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy"); 
    DateFormat targetDateFormat = new SimpleDateFormat("EEE., MMM. dd, yyyy"); 

    originalDateFormat.parse(origDateString); 
    targetDateFormat.setCalendar(originalDateFormat.getCalendar()); 
    return targetDateFormat.format(targetDateFormat.getCalendar().getTime()); 

Đó là lộn xộn nhưng cần thiết vì parse() không trả lại một giá trị bảo tồn múi giờ và format() không chấp nhận một giá trị xác định một múi giờ (lớp Date).

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