2016-03-23 22 views
17

Tôi hiện có trình phân tích cú pháp ngày Joda sử dụng DateTimeFormatterBuilder với một nửa tá định dạng ngày khác nhau mà tôi có thể nhận được.Java 8 Date tương đương với DateTimeFormatterBuilder của Joda với nhiều định dạng phân tích cú pháp?

Tôi đang di chuyển sang các thường trình Ngày của Java 8 và không thấy tương đương.

Tôi có thể làm điều gì đó như thế này bằng cách sử dụng Java 8 Ngày?

DateTimeParser[] parsers = { 
    DateTimeFormat.forPattern("yyyy/MM/dd HH:mm:ss.SSSSSS").getParser() , 
    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").getParser() , 
    DateTimeFormat.forPattern("ddMMMyyyy:HH:mm:ss.SSS Z").getParser() , 
    DateTimeFormat.forPattern("ddMMMyyyy:HH:mm:ss.SSS").getParser() , 
    DateTimeFormat.forPattern("ddMMMyyyy:HH:mm:ss.SSSSSS").getParser() , 
    DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").getParser() 
}; 

DateTimeFormatter dateTimeFormatterInput = new DateTimeFormatterBuilder() 
    .append(null, parsers).toFormatter(); 
+0

Bạn sẽ có thể quan sát một sự suy giảm nghiêm trọng hiệu suất-khôn ngoan - đặc biệt là nếu bạn có kế hoạch để thực hiện thay thế bằng cách xử lý ngoại lệ. Theo các bài kiểm tra của riêng tôi, Joda-Time nhanh hơn. Xem thêm [JDK-issue] này (https://bugs.openjdk.java.net/browse/JDK-8152273). –

Trả lời

16

Không có phương tiện trực tiếp để thực hiện việc này, nhưng bạn có thể sử dụng các phần tùy chọn. Các phần tùy chọn được đính kèm bên trong các dấu ngoặc vuông []. Điều này cho phép toàn bộ phần của Chuỗi phân tích cú pháp bị thiếu.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("" 
    + "[yyyy/MM/dd HH:mm:ss.SSSSSS]" 
    + "[yyyy-MM-dd HH:mm:ss[.SSS]]" 
    + "[ddMMMyyyy:HH:mm:ss.SSS[ Z]]" 
); 

Trình định dạng này xác định 3 phần tùy chọn lớn cho ba mẫu chính bạn có. Mỗi người trong số họ là bên trong phần tùy chọn riêng của mình.

Làm việc code demo:

public static void main(String[] args) { 
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("" 
     + "[yyyy/MM/dd HH:mm:ss.SSSSSS]" 
     + "[yyyy-MM-dd HH:mm:ss[.SSS]]" 
     + "[ddMMMyyyy:HH:mm:ss.SSS[ Z]]" 
    , Locale.ENGLISH); 
    System.out.println(LocalDateTime.parse("2016/03/23 22:00:00.256145", formatter)); 
    System.out.println(LocalDateTime.parse("2016-03-23 22:00:00", formatter)); 
    System.out.println(LocalDateTime.parse("2016-03-23 22:00:00.123", formatter)); 
    System.out.println(LocalDateTime.parse("23Mar2016:22:00:00.123", formatter)); 
    System.out.println(LocalDateTime.parse("23Mar2016:22:00:00.123 -0800", formatter)); 
} 
+0

Nếu ngôn ngữ cũng thay đổi, thì mã này sẽ không hoạt động. –

+0

Lưu ý rằng bạn không thể sử dụng điều này để định dạng, chỉ phân tích cú pháp. Khi định dạng bằng cách sử dụng trình định dạng như vậy, bạn sẽ nhận được tất cả các định dạng. Tôi đoán nếu bạn muốn một vài định dạng tùy chọn và một "mặc định" để hiển thị, bạn phải sử dụng hai phiên bản 'DateTimeFormatter' khác nhau - một với các định dạng tùy chọn được sử dụng để phân tích cú pháp và một định dạng mặc định để hiển thị. – Itai

8

Như một câu trả lời thay thế cho Tunaki, bạn cũng có thể sử dụng DateTimeFormatterBuilder:

DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder() 
    .appendPattern("[yyyy]") 
    .appendPattern("[M/d/yyyy]") 
    .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1) 
    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1) 
    .toFormatter() 
+1

Tôi không nhận được điều này để làm việc với nhiều hơn một phụ lục. Tôi tạo ra một danh sách các DateTimeFormaters và một vòng lặp với try/catch. – Avec

2

iterating trên @ giải pháp Tunaki của, sử dụng con suối, khi mã cần phải chấp nhận các mẫu khác nhau theo cách có thể định cấu hình:

DateTimeFormatter dateTimeFormatter = dateFormats.stream() 
     .map(DateTimeFormatter::ofPattern) 
     .reduce(new DateTimeFormatterBuilder(), 
       DateTimeFormatterBuilder::appendOptional, 
       (f1, f2) -> f1.append(f2.toFormatter())) 
     .toFormatter(); 

Trong trường hợp này, tôi không quan tâm đến bộ phận kết hợp của bộ giảm tốc, nhưng tôi cần nó trong chữ ký vì vậy tôi đã làm cho bộ kết hợp chính xác.

Mã này sẽ gần như tương đương với nếu các mô hình trên (yyyy/MM/dd HH:mm:ss.SSSSSS, yyyy-MM-dd HH:mm:ss[.SSS], ddMMMyyyy:HH:mm:ss.SSS[ Z]) sẽ được đưa vào dòng:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
    .appendOptional(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSSSSS") 
    .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss[.SSS]" 
    .appendOptional(DateTimeFormatter.ofPattern("ddMMMyyyy:HH:mm:ss.SSS[ Z]") 
    .toFormatter(); 
Các vấn đề liên quan