Tak jsme zase objevili jednu, pro mě překvapivou, skutečnost. Ale vezmu to popořadě. Chceme parsovat datumy s časem reprezentované stringem. Používáme Javu, takže jednoduchý úkol pro DateFormat
:
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date datum = format.parse(retez);
Tento postup má pro mě nelogickou nevýhodu. Tj. pokud si například někdo zplete pořadí měsíce a dne v měsící (u tohoto formátu to není moc pravděpodobné, ale jsou jiné, kde to jde velmi jednoduše), stejně nám to datum vytvoří. Např. parserování textu
2008-24-04 1:30:43
neznamá chybu, ale datum 2009-12-04 1:30:43
.Absolutně tuto vlastnost nechápu, ale třeba se někomu hodí. Proč je ovšem implicitní, to nepochopím nikdy. Naštěstí se dá jednoduše vypnout:
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setLenient(false);
Date datum = format.parse(retez);
Takže tentokrát už dostaneme, pro mě očekávanou,
ParseException
.A teď se pomalu blížíme k dnešnímu překvapení. Co se stane, pokud na vstupu bude řetěz
2008-04-24 1:30:43 PM
? Možnosti jsou tři: ParseException
, datum 2008-04-24 13:30:43
nebo datum 2008-04-24 1:30:43
? Osobně jsem předpokládal možnost první, přežil bych možnost druhou, ale pravdou je možnost třetí. DateFormat
si i v ne-lenient módu odignoruje část vstupního řetězce. To jsem opravdu nečekal a dost mě to zarazilo. Takže pokud někdo chce skutečně správnou funknci parserování data z řetězce, musí použít:
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setLenient(false);
ParsePosition p = new ParsePosition(0);
Date datum = format.parse(retez, p);
if (p.getIndex() < retez.length() - 1) {
throw new ParseException(...);
}
Pozor, v případě použití
ParsePosition
metoda parse
nevyhazuje výjimku, musíte si chybu ošetřit sami.Tak a máme konečně, dle mého názoru, správné parserování řetězce na text. Kód je o poznání složitější než ten, se kterým jsme začínali. Škoda, zřejmě chceme to, co není normální pro ostatní.
PS. Díky Luboši ...