2012-05-24 10 views
8

Sto cercando di analizzare un formato String in formato "gg-MM-aa" su un oggetto Date. Il problema è che cerca di indovinare il secolo per la data.Come rendere DateFormat indovinato secolo inteso?

Se specificato da 01 a 31, l'anno viene interpretato come anni 2000 (21 ° secolo) e 32 t0 99 è considerato 1900 (XX secolo).

SimpleDateFormat fm =new SimpleDateFormat("dd-MM-yy"); 
String datestr="21-11-31"; 
try { 
    Date date= fm.parse(datestr); 
    System.out.println(date); 
} catch (ParseException e) { 
} 

Qualcuno può aiutarmi? Come posso specificare che sto lavorando solo nel 21 ° secolo in modo ordinato. Non sto cercando esattamente trucchi come manipolare la stringa o spostare la data in base alla condizione.

+0

Credo che se si desidera specificare che tutte le date nel 21 ° secolo, si è in realtà probabilmente meglio fare una manipolazione delle stringhe stupido. 'S/([0-9] {2} - [0-9] {2}) - ([0-9] {2})/$ 1-20 $ 2 /'. – zebediah49

+0

Sono curioso di sapere perché l'input è in formato short year. Riesci a ottenere l'input nel formato di un anno lungo? Un'altra opzione è aggiungere "20" nel campo dell'anno usando espressioni regolari prima di analizzare la data. (.replaceFirst ("- (?! -)", "-20") – nhahtdh

+0

L'ho implementato solo con la manipolazione delle stringhe. Pensavo ci potesse essere un modo di farlo api – Edge

risposta

12

È possibile modificare il secolo che utilizza per interpretare l'immissione dei dati a 2 cifre con il metodo set2DigitYearStart().

SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yy"); 
String aDate = "03/17/40"; 
Calendar cal = Calendar.getInstance(); 
cal.clear(); 
cal.set(Calendar.YEAR, 2000); 
dateFormat.set2DigitYearStart(cal.getTime()); 
System.out.println(dateFormat.get2DigitYearStart()); 
System.out.println(dateFormat.parse(aDate)); 

stamperà 17 marzo 2040.

+1

+1 - Bella scoperta. Spero che il treno a bassa velocità ritorni :) –

+0

In realtà stavo cercando questo.Anche se sembra disordinato (probabilmente mi limiterò a manupulation di stringhe) ma risponde alla mia domanda che non sapevo su get2DigitYearStart(). Grazie – Edge

+0

Se si calcola solo l'anno 2000 e lo si mantiene in una fabbrica, è possibile eliminare il costo delle operazioni del calendario e nascondere la confusione. Funziona in entrambi i casi! – Affe

6

Dal documentation:

Per l'analisi con il modello dell'anno abbreviato ("y" o "aa"), SimpleDateFormat deve interpretare l'anno relativo abbreviato a qualche secolo. Lo fa regolando le date entro 80 anni prima e 20 anni dopo la creazione dell'istanza SimpleDateFormat. Ad esempio, utilizzando uno schema di "MM/gg/aa" e un'istanza SimpleDateFormat creata il 1 ° gennaio 1997, la stringa "01/11/12" verrà interpretata come Jan 11, 2012 mentre la stringa "05/04/64 "verrebbe interpretato come il 4 maggio 1964. Durante l'analisi, solo le stringhe composte da esattamente due cifre, come definito da Character.isDigit (char), verranno analizzate nel secolo predefinito. Qualsiasi altra stringa numerica, ad esempio una stringa di una cifra, una stringa di tre o più cifre o una stringa di due cifre che non è tutte le cifre (ad esempio, "-1"), viene interpretata letteralmente. Quindi "01/02/3" o "01/02/003" vengono analizzati utilizzando lo stesso modello di Gen 2, 3 AD. Allo stesso modo, "01/02/-3" viene analizzato come 2 gennaio 4 BC.

Non sembra menzionare alcun modo per regolare l'intervallo [-80; +20]. Ho il sospetto che la soluzione migliore è quello di espandere l'anno a due cifre nella forma di quattro cifre:

datestr = datestr.replaceFirst("-(\\d{2})$", "-20$1"); 
+0

L'API benedica il nostro comprensione di queste parole sante. Amen. – zebediah49

+0

Capisco questo, ma in realtà non risponde alla mia domanda. Possiamo avere un modo accurato di dire alla JVM se lavoriamo nel particolare secolo – Edge

+0

@Edge: vedere il paragrafo in fondo alla mia risposta. – NPE