18. února 2008

Jak nás vypek DateFormat.parse

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 ...

1. února 2008

Nová Java: Jak z toho ven ...

Už je to nějaký pátek, co jsem se zabýval vlastnostmi, které bych rád viděl v Javě 7. Něco málo se na mém názoru změnilo: jsem ještě radikálnějsí. Proč? Jsem přesvědčen, že není možné rozšířit Javu tak, aby byla zpětně kompatibilní a zároveň nabízela prvjky, které by moderní jazyk měl mít. Sun se snaží udržen nejen zpětně kompatibilní bytecode, ale i zdroják. A to je ten problém.

A jak z toho ven. Současnou Javu bych nechal takovou jakou je. Cestu ven by nám ukázala nová Java, říkejme jí např. JavaNW (New Way). JavaNW by byla překládána do stejného bytecode, ale byla by nekompatibilní na úrovni zdrojového kódu. Co to znamená? Nepřijdeme o nic z existující infrastruktury: JRE, HotSpot, Terracotta, Tomcat, ... všechno funguje. Ale to není ještě konec seznamu, protože všechny knihovny budou také použitelné: standardní knihovny Javy, Hibernate, Tapestry, FOP, ... vše budeme moci používat i nadále. Takže vlastně skoro o nic nepřijdeme, ale co vlastně získáme? To co získáme je absolutně závislé na tom, jaká bude JavaNW?

Bude JavouNW Scala? Poslední dobu jsem vyplnil studiem tohoto opěvovaného jazyka. Musím přiznat, že jeho prvky jsou opravdu úchvatné (snad se o nich někdy rozepíšu podrobněji), ale je to jiný jazyk. Syntaxe je jiná, pravda kompaktnější (není tolik upovídaná a všechny vlastnosti jsou zakomponovány tak, že do sebe krásně zapadají). Je možné použít stávající knihovny, ale Scala má také vlastní, a ty je potřeba poznat. Je mi to moc líto, protože se mi Scala opravdu moc líbí, ale nemyslím, že se Scala stane JavouNW (nikdy jsem nevěštil, tak spoléhám na to, že to neumím ...).

Tak co třeba některý ze skriptovacích jazyků: Groovy, JRuby, Jython, ... Ne nemyslím si, že budoucnost je v netypových jazycích, Scala nabízí spoustu (netroufám si napsat všechny) vlastnosti, pro které se mi tyto jazyky zamlouvají, ale je typová. Nemyslím, že jsme schopni a ochotni se připravit o výhody typového jazyka: odhalení řady chyb již při překladu, lépe fugující Code Assist, refaktoring, ... Takže JavaNW musí být něco jiného.

Takže kde vzít JavuNW? Za rozumné považuji více vyjít z Javy, aby se syntaxe nového jazyka Javě více podobala a přechod nebyl tak bolestný. Zakomponovat do něj všechny "potřebné" prvky pořádně: generiky, closures, paralelní zpracování a další. Pak by přechod mohl být pozvolný, poklidný a měli bychom nový "nabušený" jazyk.