Le date in Java

Una delle domande più ricorrenti del linguaggio Java è perchè la classe java.util.Date non fornisca alcun metodo di conversione e, oltretutto, quelli presenti sono deprecati oramai dalla versione 1.1 del JDK.
Per conoscere la risposta occorre sapere cosa questa classe rappresenta. Una istanza di java.util.Date contiene il numero di millisecondi trascorsi dalla mezzanotte del primo gennaio 1970, ora di Greenwich. Il suo significato quindi è quello di fornire le coordinate assolute di un istante di tempo, con precisione al millisecondo.
Quando si va a convertire una java.util.Date da o verso una data di calendario si hanno due ordini di problemi: il fuso orario (o timezone) e il calendario. Il fatto che l’ora mondiale sia suddivisa in timezone e cosa ben nota, un po’ meno noto è il fatto che non tutti i paesi del mondo adottano lo stesso nostro calendario Gregoriano.
Con il JDK 1.1 è stata introdotta la classe astratta java.util.Calendar, da questa classe derivano le varie implementazioni concrete dei calendari associati ai vari Locale.

java.util.Calendar è quindi astratta, ovvero non può essere istanziata direttamente. Però implementa un metodo statico getInstance() che restituisce la corretta implementazione concreta sulla base del TimeZone e del Locale. Esso è disponibile in quattro overload:

public static Calendar getInstance();
public static Calendar getInstance(TimeZone zone);
public static Calendar getInstance(Locale aLocale);
public static Calendar getInstance(TimeZone zone, Locale aLocale);

In tutti i casi il metodo restituisce una istanza che punta alla data/ora di sistema. Il tipo concreto restituito dipenderà invece dal Locale passato, nella maggior parte dei casi java.util.GregorianCalendar che è una rappresentazione del calendario Gregoriano in vigore in gran parte dei paesi del mondo (compresa ovviamente l’Italia).
Se invece provate a reperire il calendario per la Locale Thailandese:

Calendar.getInstance(new Locale("th","TH"));

vedrete il calendario risultante sarà di tipo sun.util.BuddhistCalendar.
Locale e TimeZone sono due parametri indipendenti l’uno dall’altro, nel senso che si può ottenere un Calendar relativo ad un Locale di un determinato paese del mondo ma che punta ad un fuso orario diverso. Se uno di questi parametri viene ommesso, si assume quello di sistema della JVM in esecuzione.

Una volta ottenuta una istanza di Calendar, questa deve essere utilizzata per qualsiasi conversione e/o operazione sulle date. Il metodo set() consente di impostare sul calendario una data/ora specifica; il metodo add() consente operazioni di aggiunta o sottrazione di un certo numero di unità (ore, giorni, mesi, anni, etc…); i metodi after() e before() consentono di fare comparazioni di data; infine, i metodi setTime() e getTime() consentono la conversione di una specifica data, espressa come java.util.Date, da/a questo Calendar.

JBoss, webservices e Spring

Problema: supponiamo di avere una applicazione (web o non web) basata su Spring e di voler pubblicare come web service su JBoss uno o più degli oggetti business gestiti da Spring.
La prima cosa che salta all’occhio è che qualora si utilizzino le comodissime annotazioni standard per fare il deploy del web service, il vostro oggetto manager non viene istanziato tramite l’IOC container di Spring, quindi diventa sostanzialmente inutilizzabile.
Una soluzione potrebbe essere convertire il progetto a Ejb3, chi può farlo lo faccia, ma chi non può? Per non parlare di chi non vuole…
In questi casi il metodo conveniente è quello di derivare la vostra classe che esporrà il web service da una n-esima classe di supporto di Spring, la SpringBeanAutowiringSupport. Questa classe astratta abilita l’annotazione @Autowire su qualsiasi istanza di oggetto purchè creata all’interno di una Web Application Spring-based. In questo modo potete “iniettare” oggetti configurati nel vostro IOC container di Spring nel vostro Web Service, esattamente come se fosse esso stesso un oggetto di Spring, continuando quindi ad utilizzare il paradigma del inversion of control.