2012-05-24 16 views
8

Próbuję parsować String w formacie "dd-MM-yy" do obiektu Date. Problem polega na tym, że próbuje odgadnąć wiek na datę.Jak sprawić, by DateFormat odgadł zamierzone stulecie?

Po określeniu od 01 do 31, rok jest interpretowany jako 2000s (XXI wiek), a 32 t0 99 jest uważane za lata 1900 (XX w.).

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) { 
} 

Czy ktoś może mi pomóc? Jak mogę określić, że pracuję tylko w 21 wieku starannie. Nie próbuję dokładnie szukać sztuczek takich jak manipulowanie ciągiem znaków lub przesuwanie daty w oparciu o warunek.

+0

Wierzę, że jeśli chcesz, aby określić, że wszystkie terminy są w 21 wieku, jesteś rzeczywiście chyba lepiej robić głupie manipulacji ciąg off. 's/([0-9] {2} - [0-9] {2}) - ([0-9] {2})/$ 1-20 $ 2 /'. – zebediah49

+0

Jestem ciekawy, dlaczego dane wejściowe są w formacie krótkiego roku. Czy możesz uzyskać dane wejściowe w formacie całorocznym? Inną opcją jest dodanie "20" w polu roku za pomocą wyrażeń regularnych przed analizą daty. (.replaceFirst ("- (?! -)", "-20") – nhahtdh

+0

Wdrożyłem go tylko poprzez manipulację ciągami, tylko myślałem, że może być w ten sposób APi – Edge

Odpowiedz

12

Można zmienić wiek wykorzystuje do interpretowania 2-cyfrowy wprowadzanie danych za pomocą metody 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)); 

drukuje 17 marca 2040.

+1

+1 - Miłe znalezisko. Mam nadzieję, że pociąg powrotny wraca :) –

+0

Właściwie to szukałem.Chociaż wygląda na niechlujnie (prawdopodobnie będę się trzymał z manewrowaniem strunami), ale odpowiada na moje zamierzone pytanie, którego nie wiedziałem o get2DigitYearStart(). Thanx – Edge

+0

Jeśli po prostu obliczysz rok 2000 i zatrzymasz go w fabryce, możesz wyeliminować koszty operacji kalendarza i ukryć bałagan. Działa tak czy inaczej! – Affe

6

Z documentation:

Do parsowania ze skróconą roku wzorca („y” lub „yy”) należy interpretować SimpleDateFormat skróconej roku w stosunku do pewnego wieku. Robi to, dostosowując daty do 80 lat wcześniej i 20 lat po utworzeniu instancji SimpleDateFormat. Na przykład, używając wzorca "MM/dd/yy" i instancji SimpleDateFormat utworzonej 1 stycznia 1997 r., Ciąg "01/11/12" zostanie zinterpretowany jako 11 stycznia 2012 r., Podczas gdy ciąg "05/04/64 "byłby interpretowany jako 4 maja 1964. Podczas parsowania, tylko łańcuchy składające się dokładnie z dwóch cyfr, jak zdefiniowano w Character.isDigit (char), zostaną sparsowane do domyślnego wieku. Każdy inny łańcuch liczbowy, taki jak ciąg jednocyfrowy, ciąg trzyliterowy lub ciąg dwucyfrowy, który nie jest cyfrą (na przykład "-1"), interpretowany jest dosłownie. Tak więc "01/03/3" lub "01/02/003" są analizowane przy użyciu tego samego wzorca, jak 2 stycznia, 3 AD. Podobnie "01/02/-3" jest analizowany jako 2 stycznia 4 pne.

Wygląda na to, że nie wspomina się o żadnym sposobie regulacji zakresu [-80; +20]. Podejrzewam, że najlepiej jest, aby rozwinąć roku dwucyfrowy w postaci czterocyfrowej:

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

Niech API pobłogosławi nasze zrozumienie tych świętych słów. Amen. – zebediah49

+0

Rozumiem to, ale tak naprawdę nie odpowiada na moje pytanie. Czy możemy mieć przyjemny sposób mówienia JVM, jeśli pracujemy w danym wieku? – Edge

+0

@Edge: Zobacz akapit na dole mojej odpowiedzi. – NPE

Powiązane problemy