2015-09-10 12 views
6

Nếu tôi sử dụng mẫu như d/M/yy để tạo Java 8 DateTimeFormatter (ví dụ: sử dụng DateTimeFormatter.ofPattern(pattern); (mà tôi sẽ chỉ sử dụng để phân tích cú pháp, không định dạng), nó sẽ diễn giải tất cả hai năm là 20xx, ví dụ: phân tích chuỗi như 13/5/99 được hiểu là 2099-05-13, mà trong trường hợp của tôi là sai (có nghĩa là vào năm 1999).Làm thế nào để thay đổi ngày cơ sở để phân tích hai năm thư với Java 8 DateTimeFormatter?

Trong đơn của tôi, tôi đang cố phân tích các ngày từ các tài liệu OCR, có thể vẫn còn từ 90ies, do đó, có hành vi SimpleDateFormat cũ của việc giải thích ngày để được trong vòng 80 năm trước và 20 năm sau ngày hiện tại phù hợp với tôi khá tốt.Nhưng vì nhiều lý do tôi vẫn đang tìm cách chuyển đổi toàn bộ logic phân tích ngày sang Java 8 DateTimeFormatters.

Nhìn qua mã nguồn Java, tôi thấy rằng tất cả điều này được diễn giải liên quan đến hằng số ReducedPrinterParser.BASE_DATE, nhưng tôi không thấy cách nào để thay đổi giá trị được sử dụng khi tạo trình định dạng của riêng tôi từ một mẫu. Điều này đơn giản là không thể hoặc tôi đã bỏ lỡ một số khả năng xác định hành vi phân tích cú pháp hai năm?

+0

có thể trùng lặp của [Phân tích chuỗi ngày địa phương không sử dụng thế kỷ mong muốn] (http://stackoverflow.com/questions/29490893/parsing-string-to-local-date-doesnt-use-desired-century) –

Trả lời

9

Bạn có thể tạo ra một định dạng tùy chỉnh, ví dụ cho mô hình d/M/yy:

new DateTimeFormatterBuilder() 
     .appendPattern("d/M/") 
     .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.now().minusYears(80)) 

Ví dụ sử dụng:

public static void main(String[] args) throws Exception { 
    DateTimeFormatter fmt = new DateTimeFormatterBuilder() 
      .appendPattern("d/M/") 
      .appendValueReduced(ChronoField.YEAR_OF_ERA, 2, 2, LocalDate.now().minusYears(80)) 
      .toFormatter(); 
    parse("13/5/99", fmt); 
    parse("13/5/36", fmt); 
    parse("13/5/35", fmt); 
    parse("13/5/34", fmt); 
    parse("13/5/33", fmt); 
} 

private static void parse(String date, DateTimeFormatter fmt) { 
    System.out.println(date + " = " + LocalDate.parse(date, fmt)); 
} 

mà in:

13/5/99 = 1999-05-13
13/5/36 = 1936-05-13
13/5/35 = 1935-05-13
13/5/34 = 2034-05-13
13/5/33 = 2033-05-13

+0

Một chút cồng kềnh (vì tôi sẽ có về cơ bản phân tích danh sách mẫu hiện có của tôi, kiểm tra xem nó có chứa "yy" rồi xây dựng trình định dạng như bạn mô tả), nhưng chắc chắn có thể làm được, cảm ơn, tôi không biết tôi có thể kết hợp một phần của mẫu với các tùy chọn khác như thế! – David

+2

Ồ, và gợi ý cho mọi người gặp phải vấn đề tương tự: appendValueReduced (ChronoField.YEAR_OF_ERA, 2, 4, LocalDate.now(). MinusYears (80)) cho bạn khả năng phân tích cả hai ký tự và bốn năm ký tự ! – David

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