Newsgroup: it.comp.java
Titolo: instanza Date in UTC TimeZone

ciao a tutti
Ho la necessità di memorizzare nel database sempre i campi datetime
nel valore del timezone UTC a prescindere dal timezone del desktop
quando riprendo nel desktop con java la data la converto dal valore
UTC al valore del timezone del desktop (o meglio la rappresento nel
local timezone)
Nel fare queste due conversioni non mi è stato possibile ottenere una
instanza di Date con la notazione del TimeZone UTC
Qualcuno sa come si fa ?
Allego questo codice con cui ho faccio le due conversioni; io ho
trovato solo questa strada
A= da stringa di database (che contene un valore di data espresso in
UTC) a campo Date con TimeZone del desktop
B= da campo Date con TimeZone del desktop a campo Date con valore di
data in TimeZone UTC pronto per essere portato nel db (verrà preso il
valore ignorando il tz)
questo è il risultato:
A1) Stringa proveniente dal db=2005-04-15 07:11:20
A2) CampoDate in local tz=Fri Apr 15 09:11:20 CEST 2005
==========================================
B1) CampoDate in local tz=Fri Apr 15 09:11:20 CEST 2005
B2) data con valore utc per db= Fri Apr 15 07:11:20 CEST 2005
come si noterà il risultato di B è un campo date con il valore di data
esatto (-2ore rispetto al nostro solare)
ma non sono riuscito a trovare una soluzion per avere l'instalza di
Date che riporti anche la notazione UTC
anche il risultato di A è a mio giudizio anomalo, perchè mi sarei
aspettatto un campo date con timezone UTC
possibile che non si possa ottenere una instalza di Date con la
notazione UTC ?
grazie saluti
import java.util.*;
import java.text.*;
public class ProvaDataOra2 {
	public ProvaDataOra2 () {
	}
		public void conversioni() {
		//da db a date
		String dbStr = "2005-04-15 07:11:20";
		System.out.println( "A1) Stringa proveniente dal db="+dbStr);
		SimpleDateFormat dbFormat = new SimpleDateFormat("yyyy-MM-dd
HH:mm:ss");
		dbFormat.setTimeZone( TimeZone.getTimeZone("UTC"));//la sorgente del
db è gmt
		//dbFormat.setTimeZone( TimeZone.getTimeZone(
System.getProperty("user.timezone")) );
		Date localDate =null;
		try {
			//GregorianCalendar calendar = new GregorianCalendar(); //local TZ
			//calendar.setTime(dbFormat.parse(dbStr));
			//localDate = calendar.getTime();
			localDate = dbFormat.parse(dbStr);
			System.out.println( "A2) CampoDate in local tz="+localDate);
			//stampa(calendar);
		}catch (ParseException pe) {
			System.out.println( "errore "+pe.toString());
		}
		//da dateLocal a DateUTC per poter andare nel db
		System.out.println( "==========================================");
		System.out.println( "B1) CampoDate in local tz="+localDate);
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(localDate);
		calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
		//stampa(calendar);
		//System.out.println("dtc="+calendar.getTime()); //time data in
local
		GregorianCalendar calendar2 = new GregorianCalendar (
				calendar.get(Calendar.YEAR),
				calendar.get(Calendar.MONTH),
				calendar.get(Calendar.DATE),
				calendar.get(Calendar.HOUR_OF_DAY),
				calendar.get(Calendar.MINUTE),
				calendar.get(Calendar.SECOND)
				);
		//calendar2.setTimeZone(TimeZone.getTimeZone("UTC"));
		//System.out.println("dtc2="+calendar2.getTime());
		//non funziona => calendar2.setTimeZone(TimeZone.getTimeZone("UTC"));
		//System.out.println("dtc2B="+calendar2.getTime());
		Date tt = calendar2.getTime();
		System.out.println("B2) data con valore utc per db= "+tt);
	}
	public static void main(String[] args) {
			new ProvaDataOra2().conversioni();
		}
}

 instanza di Date con la notazione del TimeZone UTC
Un'istanza della classe Date in java non è legata ad alcun TimeZone.
L'istanza rappresenta un istante assoluto nel tempo.
Per ottenere la sua rappresentazione in gg/mm/aa hh:mm:ss così come
conosciuto a noi occidentali è necessario passare sempre da un'istanza
della classe Calendar (nel nostro caso il GregorianCalendar). Esistono
poi alcune classi come il SimpleDateFormat che utilizzando un'istanza
del Calendar ti permettono di avere la formattazione 'facilitata'
della data. Lo stesso metodo toString() che tu usi nel tuo codice è
implementato basandosi su un SimpleDateFormat.
Quando poi si tratta di rappresentare le ore, entra in gioco il
TimeZone: come hai scoperto un'istanza della classe Date, produce
diverse rappresentazioni alfanumeriche in base al TimeZone corrente o
a quello impostato sul SimpleDateFormat. E' possibile cambiare il
TimeZone utilizzato da un'applicazione usando i metodi forniti dalla
classe stessa.
Se provi a fare:
Date d = new Date();
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(d);
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
System.out.println(d);
otterrai rispettivamente la da e l'ora UTC e la nostra, ma come vedi
l'istanza è la stessa.
Se poi stai lavorando con un database, ti sconsiglio di
leggere/scrivere le date in formato stringa, a meno che tu non abbia
deciso di memorizzarle su DB sotto forma di stringhe (ma questo te lo
sconsiglio ancora di più).
Quando leggi da un ResultSet, usa il metodo getDate() che ti
restituisce un'istanza di java.sql.Date e non devi preoccuparti di
TimeZone e altre menate del genere. Quando invece scrivi usa il metodo
setDate() e sei a posto.
A proposito che DB stai usando ?

 A proposito che DB stai usando ?
uso mysql ed i campi date/datetime li lacio nel formato nativo di
mysql (standard sql)
ho un db in un server remoto (in usa) e vi accedono utenti con fusi
orari differenti, quindi memorizzo sempre UTC e quando rileggo le
mostro nel formato del rispettivo desktop
anche se leggendo, leggo non verso un date ma verso una string perchè
così con la .parse(dbStr) del SimpleDateFormat di un valore utc, mi
ritrovo una instanza di Date co il valore del time converita nel
timezone del desktop
così quando mostro a video il campo Date ce l'ho già completo anche
della segnatura del tz familiare all'utente e riportato al suo di
orario

 mostro nel formato del rispettivo desktop
Non conosco MySql, ma quello che mi aspetto, visto il comportamento
degli altri database (DB2, Oracle e SQLServer), è di estrarre dal
ResultSet un oggetto di tipo Date e di portarlo a video formattandolo
secondo il TimeZone dell'utente collegato utilizzando un'istanza di
SimpleDateFormat su cui imposti il TimeZone da usare. Questo ti
formatta la data così come ti serve.
Non ho capito se hai un'applicazione che gira negli stati uniti e
serve pagine in tutto il mondo o se invece hai n applicazioni che da
tutto il mondo si collegano al tuo DB negli stati uniti.
Nella prima ipotesi devi stabilire qual'è il TimeZone del tuo utente
collegato (e qui devi trovare tu il modo per saperlo) e usare il
SimpleDateFormat impostando di volta in volta il TimeZone corretto.
Nella seconda ipotesi invece ciascuna virtual machine gira con il
timezone del sistema operativo e probabilmente il tutto funziona
correttamente. Altrimenti puoi tranquillamente impostare il TimeZone
con il metodo setDefault, in modo che tutta l'applicazione usi quello
che tu desideri.
Ti consiglio di farti un giro sulla documentazione delle classi Java,
e sul tutorial alla sezione sull'internazionalizzazione
http://java.sun.com/docs/books/tutorial/i18n/format/dateintro.html
E buona fortuna...

...

grazie Bingo
(lavorai con il DB2 su host os/390 cia cobol, ora sviluppo in java
sotto gpl e db mysql)
ho il database mysql in uno spazio server negli usa
http://www.westhost.com/
 e vi accedo da li via web in php che da
desktop remoti in java dall'italia e dall'africa
quindi ho deciso di memorizzare sempre nel db in utc e portare a video
sempre del localtz
alla prossima ciao