mercoledì 20 ottobre 2010

API - Date e numeri

La parte relativa alle API di Date e Numeri in Java (per la certificazione Programmer) riguarda le seguenti classi:

  • Date
  • Calendar
  • Locale
  • DateFormat
  • NumberFormat
a queste possiamo aggiungere l'uso di TimeZone, per conoscenza personale.

Vediamo subito le potenzialità e funzionalità di ogni classe:


Date
La classe Date è quasi totalmente deprecata; viene utilizzata per fare da tramite tra Calendar e DateFormat; non usatela mai direttamente (se i metodi sono deprecati un motivo ci sarà).
Calendar
Calendar si ottiene tramite Factory Method (Calendar.getInstance(););
I metodi per ottenerla permettono di indicare un Locale, una TimeZone o entrambe; importante notare come il Locale non sia più modificabile in seguito, laddove esiste il metodo setTimeZone(..) per modificare la TimeZone.
Facile fare confusione per via di questi due oggetti; cerchiamo di capire meglio come funzionano:
Locale:
Il locale indica i dati relativi a informazioni come primo giorno della settimana, numero di settimane nel mese e via dicendo; non riguarda minimamente il fuso orario del Calendar;
TimeZone:
La timezone viene utilizzata internamente dall'oggetto per i seguenti metodi:
  • get(...)
  • set(...)
Se eseguiamo il seguente codice
Calendar it = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
Calendar us = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println(it.get(Calendar.HOUR_OF_DAY));
System.out.println(us.get(Calendar.HOUR_OF_DAY));
otterremo
23
14
poiché il metodo get viene influenzato dalla timezone.
Se eseguissimo invece
Calendar it = Calendar.getInstance(TimeZone.getTimeZone("Europe/Rome"));
Calendar us = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println(it.getTime());
System.out.println(us.getTime());
otterremmo
Tue Oct 19 23:51:28 CEST 2010
Tue Oct 19 23:51:28 CEST 2010
questo mostra come get e set siano influenzati dalla timezone, mentre getTime() non lo sia.

I metodi importanti di Calendar sono:
  • set e get
  • add
  • roll
Tutti e quattro i metodi hanno la signature: add(int field, int amount), dove field indica il tipo di campo su cui lavorare, e amount il valore di modifica; ad esempio:
it.add(Calendar.DAY_OF_MONTH, 1);
System.out.println(it.getTime());
it.add(Calendar.MONTH, 1);
System.out.println(it.getTime());
it.add(Calendar.YEAR, 1);
System.out.println(it.getTime());
e relativi :
Wed Oct 20 00:11:12 CEST 2010
Thu Oct 21 00:11:12 CEST 2010
Sun Nov 21 00:11:12 CET 2010
Mon Nov 21 00:11:12 CET 2011

Il metodo setLenient(boolean) rende i calcoli più rilassati; abbiamo quindi
Calendar now = Calendar.getInstance(); now.set(2010, 12, 32); now.setLenient(false); System.out.println(now.get(Calendar.DAY_OF_MONTH)); //eccezione java.lang.IllegalArgumentException: MONTH now.setLenient(true); System.out.println(now.get(Calendar.DAY_OF_MONTH)); //corretto


Locale
Indica una determinata area geografica, con valori di lingua propri; ha due costruttori principali:
  • Locale(String language);
  • Locale(String language, String country);
e inoltre esistono costanti per ogni Language e County definiti a sistema; il locale serve per identificare un luogo, e con i Format permette di visualizzare dati localizzati (nel formato corretto, non con valori differenti).
Il metodo statico Locale.getAvailableLocales() permette di ottenere tutti i locali definiti sulla macchina.
DateFormat
Ha tre forme di Factory Method, dipendenti da che dato si vuole avere: data, ora, data e ora; vediamo direttamente il più completo tra i tre:
DateFormat df = DateFormat.getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)
il DateFormat ottenuto è relativo al Locale indicato, e mostra più o meno informazioni (in base allo stile); vediamo in azione:
Date d = Calendar.getInstance().getTime();
DateFormat dfS = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.ITALY);
DateFormat dfD = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.ITALY);
DateFormat dfL = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.ITALY);
DateFormat dfF = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.ITALY);
System.out.println(dfS.format(d));
System.out.println(dfD.format(d));
System.out.println(dfL.format(d));
System.out.println(dfF.format(d));
e i suoi risultati:
20/10/10 0.03
20-ott-2010 0.03.02
20 ottobre 2010 0.03.02 CEST
mercoledì 20 ottobre 2010 0.03.02 CEST
come vediamo, sono tutti relativi al Locale indicato; proviamo ad eseguirne uno su un locale differente:
DateFormat dfLUSA = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
System.out.println(dfLUSA.format(d));
e risultato:
October 20, 2010 12:04:57 AM CEST

Vediamo quindi che il Locale varia soltanto il tipo di visualizzazione del dato; se vogliamo modificare anche il valore dell'ora, basta usare la TimeZone, proprio come con il Calendar:
DateFormat dfLUSA = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
System.out.println(dfLUSA.format(d));
dfLUSA.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println(dfLUSA.format(d));
e i risultati:
October 20, 2010 12:07:05 AM CEST
October 19, 2010 3:07:05 PM PDT

La logica opposta si applica al metodo DateFormat.Parse(String), che prende una stringa e restituisce una Date associata; vediamo alcuni esempi:
DateFormat dfS = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.ITALY);
Date ds = dfS.parse("20/10/10 0.11"); //restituisce un Date valido
Date ds2 = dfS.parse("Wed Oct 20 00:13:55 CEST 2010"); //lancia eccezione java.text.ParseException: Unparseable date: "Wed Oct 20 00:13:55 CEST 2010"
Attenzione anche a:
dfLUSA.parse("October 19, 2010 3:16:12 PM PDT"); //corretto
dfL.parse("October 19, 2010 3:16:12 PM PDT"); //eccezione
poiché October non viene riconosciuto nel locale italiano.
Un metodo di utilità è setLenient(true) che rende il parsing più rilassato; se proviamo a fare il parsing della data 40/12/2010 otteniamo:
NumberFormat
NumberFormat include tre categorie di formattazione:
  • Numeri
NumberFormat nfIT  = NumberFormat.getNumberInstance(Locale.ITALY);
NumberFormat nfUS  = NumberFormat.getNumberInstance(Locale.US);
NumberFormat nfJA  = NumberFormat.getNumberInstance(Locale.JAPAN);
System.out.println(nfIT.format(12345.67890));
System.out.println(nfUS.format(12345.67890));
System.out.println(nfJA.format(12345.67890));
12.345,679
12,345.679
12,345.679
Vediamo subito che le differenze sono relative al carattere delle migliaia e dei decimali
  • Valute
NumberFormat nfIT  = NumberFormat.getCurrencyInstance(Locale.ITALY);
NumberFormat nfUS  = NumberFormat.getCurrencyInstance(Locale.US);
NumberFormat nfJA  = NumberFormat.getCurrencyInstance(Locale.JAPAN);
System.out.println(nfIT.format(12345.67890));
System.out.println(nfUS.format(12345.67890));
System.out.println(nfJA.format(12345.67890));

€ 12.345,68
$12,345.68
?12,346
Qui abbiamo due novità: il simbolo della valuta cambia (e nel caso del Giappone non lo abbiamo sul sistema), e in alcuni casi possiamo non avere valori decimali (come in Italia, quando avevamo la Lira)
  • Percentuali
NumberFormat nfIT  = NumberFormat.getPercentInstance(Locale.ITALY); NumberFormat nfUS  = NumberFormat.getPercentInstance(Locale.US);
NumberFormat nfJA  = NumberFormat.getPercentInstance(Locale.JAPAN);
System.out.println(nfIT.format(12345.67890));
System.out.println(nfUS.format(12345.67890));
System.out.println(nfJA.format(12345.67890));
1.234.568%
1,234,568%
1,234,568%
Le variazioni sono uguali a quelle dei Numeri;

Anche nel caso dei numeri abbiamo il metodo NumberFormat.Parse(String) che segue la stessa logica del DateFormat.Parse(String)

Il codice di questi esempi è racchiuso in un solo file java

Nessun commento:

Posta un commento