2016-05-16 39 views
5

Tôi cố gắng để sử dụng Java 8 ngày mẫu mới thay vì Joda và tôi có vấn đề sau đây:Java 8 LocalDateTime ZonedDateTime không thể phân tích ngày với múi giờ

Cả

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z")) 

LocalDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z")) 

ném ngoại lệ 'java.time.format.DateTimeParseException'. Trong khi

org.joda.time.DateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormat.forPattern("dd/MM/yy HH:mm.ss.SSS Z")) 

hoạt động tốt.

Nguyên nhân của ngoại lệ là:

java.time.format.DateTimeParseException: Văn bản '02/05/16 11: 51.12.083 04: 30' không thể được phân tích ở chỉ số 22

Tôi có làm gì sai không?

+2

Các bạn đã thử OffsetDateTime? Nó không chứa đủ thông tin để biết múi giờ thực tế; tất cả nó mang là bù đắp từ UTC. –

+0

Mặc dù từ ví dụ trong [tài liệu] (https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html), có vẻ như dấu hai chấm được chấp nhận là vùng phân tách bù trừ nhưng khi bạn thử nó, nó ném ngoại lệ. nếu bạn chỉ cần loại bỏ các đại tràng nó sẽ làm việc. vì vậy chuỗi ngày giờ của bạn phải là '02/05/16 11: 51.12.083 + 0430' –

+0

@Hank DI đã thử OffsetDateTime.parse này ("02/05/16 11: 51.12.083 +04: 30", DateTimeFormatter.ofPattern ("dd/MM/YY HH: mm.ss.SSS Z")) nhưng tôi vẫn nhận được ngoại lệ tương tự. – ampofila

Trả lời

5

Nếu bạn đọc the javadoc of DateTimeFormatter, bạn sẽ tìm thấy một phần chi tiết làm thế nào để sử dụng Z bù đắp (nhấn mạnh mỏ):

Bù đắp Z: Định dạng này dựa trên số mẫu chữ. Một, hai hoặc ba chữ cái xuất ra giờ và phút, không có dấu hai chấm, chẳng hạn như '+0130'. Đầu ra sẽ là '+0000' khi độ lệch bằng 0. Bốn chữ cái xuất ra dạng đầy đủ của offset cục bộ, tương đương với bốn chữ cái của Offset-O. Đầu ra sẽ là văn bản bù trừ cục bộ tương ứng nếu giá trị offset bằng 0. Năm chữ cái xuất ra giờ, phút, với tùy chọn thứ hai nếu khác 0, với dấu hai chấm. Nó xuất ra 'Z' nếu giá trị offset bằng 0. Sáu chữ cái trở lên ném IllegalArgumentException.

Vì vậy, sử dụng 5 Z s sẽ làm việc như mong đợi:

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", 
        DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS ZZZZZ")); 

Lưu ý rằng bạn có thể đạt được kết quả tương tự với:

  • z
  • zz
  • zzz
  • zzzz
  • xxx
  • XXX
  • xxxxx
  • XXXXX
0

Bạn cần sử dụng XXX để bù vùng. Điều này sẽ làm việc cho ZonedDateTimeOffsetDateTime

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 

Nó sẽ phân tích với LocalDateTime là tốt, nhưng vùng bù đắp sẽ được rút ngắn.

+0

Tôi đã thử điều này, vẫn là ngoại lệ tương tự. (ZonedDateTime.parse ("02/05/16 11: 51.12.083 +04: 30", DateTimeFormatter.ofPattern ("dd/MM/YY HH: mm.ss.SSS X")))) – ampofila

1

Tôi tìm thấy câu trả lời trong bài viết này Unparsable Date with colon-separated timezone

Để phân tích một dấu thời gian mà mang một múi giờ bằng dấu chấm phẩy thay vì X hoặc Z như javadoc DateFormatter chỉ ra, bạn cần phải sử dụng XXX. Tất cả các công việc sau đây:

LocalDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 

OffsetDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 

ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS XXX")) 
0

Sử dụng DateTimeFormatterBuilder để có được kiểm soát chính xác của bộ phân tích và sử dụng appendOffsetId công trình:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
     .appendValue(ChronoField.DAY_OF_MONTH, 2) 
     .appendLiteral('/') 
     .appendValue(ChronoField.MONTH_OF_YEAR, 2) 
     .appendLiteral('/') 
     .appendValueReduced(ChronoField.YEAR, 2, 2, 2000) 
     .appendLiteral(' ') 
     .appendValue(ChronoField.HOUR_OF_DAY) 
     .appendLiteral(':') 
     .appendValue(ChronoField.MINUTE_OF_HOUR) 
     .appendLiteral('.') 
     .appendValue(ChronoField.SECOND_OF_MINUTE) 
     .appendLiteral('.') 
     .appendValue(ChronoField.MILLI_OF_SECOND) 
     .appendLiteral(' ') 
     .appendOffsetId() 
     .toFormatter(); 

OffsetDateTime.parse("02/05/16 11:51.12.083 +04:30", formatter); 
Các vấn đề liên quan