2016-03-17 17 views
9

Ho bisogno di analizzare una stringa in un LocalDate. La stringa appare come 31.* 03 2016 in termini di espressioni regolari (ad esempio, .* significa che potrebbero essere presenti 0 o più caratteri sconosciuti dopo il numero del giorno).Wildcard in DateTimeFormatter

ingresso Esempio/uscita: 31xy 03 2016 ==>2016-03-31

speravo di trovare una sintassi jolly nella documentazione DateTimeFormatter per consentire a un modello come ad esempio:

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

ma non ho trovato nulla .

C'è un modo semplice per esprimere caratteri sconosciuti opzionali con un DateTimeFormatter?

ps: Posso ovviamente modificare la stringa prima di analizzarla ma non è quello che sto chiedendo.

+0

C'è un motivo per cui non si desidera sottoporre a pre-elaborazione la stringa prima di passarla a 'DateTimeFormatter'? Qualcos'altro che puoi fare è creare la tua classe che estenda 'DateTimeFormatter' e sovrascriva il metodo' ofPattern() ', ma questo non sembra consigliabile. –

+0

Preferirei una soluzione elegante con DateTimeFormatter - se non esiste andrò per il piano B. DateTimeFormatter è finale quindi non è estendibile. – assylias

+0

Ah non ne ero consapevole, buono a sapersi! –

risposta

5

Non esiste un supporto diretto per questo in java.time.

Il più vicino sarebbe utilizzare parse(CharSequence,ParsePosition) utilizzando due diversi formattatori.

// 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); 

Anche se quanto sopra non è stato testato, dovrebbe funzionare. Tuttavia, sarebbe molto più semplice analizzarlo manualmente.

+0

Forse un parser "clemente" che salta semplicemente i caratteri non sostituibili? (L'utilizzo di uno stile risolutore LENIENT non funziona) – assylias

2

lo farei in due fasi, utilizzare un'espressione regolare per ottenere la stringa originale in qualcosa che LocalDate in grado di analizzare, per esempio:

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); 

io so che non è quello che hai chiesto.

+1

Non è sempre possibile ottenere ciò che si desidera. Ma se provi a volte, beh, potresti scoprire di ottenere ciò di cui hai bisogno. –

Problemi correlati