2016-03-17 19 views
9

Tôi cần phải phân tích cú pháp một chuỗi thành một số LocalDate. Chuỗi trông giống như 31.* 03 2016 trong các thuật ngữ regex (nghĩa là .* có nghĩa là có thể có 0 hoặc nhiều ký tự không xác định sau số ngày).Ký tự đại diện trong DateTimeFormatter

Ví dụ đầu vào/đầu ra: 31xy 03 2016 ==>2016-03-31

Tôi đã hy vọng để tìm thấy một cú pháp wildcard trong tài liệu DateTimeFormatter để cho phép một mô hình như:

LocalDate.parse("31xy 03 2016", DateTimeFormatter.ofPattern("dd[.*] MM yyyy")); 

nhưng tôi không thể tìm thấy bất cứ điều gì .

Có cách nào đơn giản để thể hiện các ký tự không xác định tùy chọn với số DateTimeFormatter không?

ps: Tôi rõ ràng có thể sửa đổi chuỗi trước khi phân tích cú pháp nhưng đó không phải là những gì tôi yêu cầu.

+0

Có lý do nào bạn không muốn xử lý trước chuỗi trước khi chuyển nó vào 'DateTimeFormatter' không? Một cái gì đó khác bạn có thể làm là tạo ra lớp của riêng bạn mà mở rộng 'DateTimeFormatter' và ghi đè phương thức' ofPattern() ', nhưng điều này dường như không được khuyến khích. –

+0

Tôi muốn một giải pháp thanh lịch với DateTimeFormatter - nếu nó không tồn tại tôi sẽ đi cho kế hoạch B. DateTimeFormatter là cuối cùng như vậy là không thể mở rộng. – assylias

+0

Ah đã không nhận thức được rằng, tốt để biết! –

Trả lời

5

Không có hỗ trợ trực tiếp cho điều này trong java.time.

Cách gần nhất là sử dụng parse(CharSequence,ParsePosition) sử dụng hai trình định dạng khác nhau.

// create the formatter for the first half 
DateTimeFormatter a = DateTimeFormatter.ofPattern("dd") 

// setup a ParsePosition to keep track of where we are in the parse 
ParsePosition pp = new ParsePosition(); 

// parse the date, which will update the index in the ParsePosition 
String str = "31xy 03 2016"; 
int dom = a.parse(str, pp).get(DAY_OF_MONTH); 

// some logic to skip the messy 'xy' part 
// logic must update the ParsePosition to the start of the month section 
pp.setIndex(???) 

// use the parsed day-of-month in the formatter for the month and year 
DateTimeFormatter b = DateTimeFormatter.ofPattern("MM yyyy") 
    .parseDefaulting(DAY_OF_MONTH, dom); 

// parse the date, using the *same* ParsePosition 
LocalDate date = b.parse(str, pp).query(LocalDate::from); 

Trong khi ở trên chưa được kiểm tra, về cơ bản, nó sẽ hoạt động. Tuy nhiên, nó sẽ dễ dàng phân tích cú pháp nó theo cách thủ công hơn.

+0

Có thể một trình phân tích cú pháp "khoan dung" chỉ bỏ qua các ký tự không được phân bổ? (Sử dụng kiểu giải quyết LENIENT không hoạt động) – assylias

2

tôi muốn làm điều đó trong hai bước, sử dụng một regexp để có được chuỗi ban đầu thành một cái gì đó LOCALDATE có thể phân tích cú pháp, ví dụ:

String dateSource = "31xy 03 2016"; 
String normalizedDate = dateSource.replaceFirst("^(\\d+).*? (\\d+ \\d+)", "$1 $2"); 
LocalDate date = LocalDate.parse(normalizedDate, DateTimeFormatter.ofPattern("dd MM yyyy")); 
System.out.println(date); 

Tôi biết nó không phải những gì bạn yêu cầu.

+1

Bạn không thể luôn có được những gì bạn muốn. Nhưng nếu bạn cố gắng đôi khi, bạn cũng có thể tìm thấy bạn có được những gì bạn cần. –

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