L’utilizzo delle date è sempre stata una cosa semplice in Xojo. La classe Date del Framework “classico” permette di crearle ed utilizzarle con poche istruzioni. Ma questa classe ha diversi limiti e può portare a pericolosi errori.
Vediamo in questo post come utilizzare la nuova classe Date del nuovo Framework di Xojo.
Nel framework classico per creare la data che corrisponde al momento attuale possiamo scrivere:
dim adesso as New Date |
La data ottenuta è un oggetto di cui possiamo leggere e modificarne le proprietà.
Ad esempio se vogliamo ottenere l’ultimo giorno del mese rappresentato dalla data possiamo scrivere:
dim ultimoGiorno as new Date(2017, 02, 25) //possiamo creare la data anche impostando gli elementi ultimoGiorno.Month=ultimoGiorno.Month+1 ultimoGiorno.Day=0 dim dataOttenuta as string=ultimoGiorno.sqlDate //Data ottenuta varrà 2017-02-28 |
Ma proprio questo frammento di codice mostra alcuni dei potenziali errori che si possono incontrare: Prima di tutto “muovendo” le date bisogna seguire un ordine preciso altrimenti il risultato ottenuto sarà diverso, inoltre, e questo è spesso più subdolo, viene modificato l’oggetto utilizzato.
Poniamo di avere una funzione che restituisca la data relativa alla fine del mese della data passata come argomento:
Function fineMese(dataCorrente as Date) as Date dataCorrente.Month=dataCorrente.Month+1 dataCorrente.Day=0 return dataCorrente End Function //Usiamo la funzione dim dataIniziale as Date=new Date dataIniziale.sqlDate="2017-02-25" //Altro modo per inizializzare la data magari da un valore di un campo in un db dim dataFineMese=fineMese(dataCorrente) |
Ma a questo punto le due date rappresentano lo stesso oggetto e la dataIniziale non è più la data da cui siamo partiti ma l’ultimo giorno del mese.
Questo perché modifichiamo l’oggetto passato come parametro e questi sono passati sempre per riferimento.
Ora questo problema è facilmente evitabile creando una nuova data all’interno della funzione e che rappresenti la stessa data dell’oggetto originale, ma molti programmatori, specie quelli alle prime armi si scordano di questo “effetto” sugli oggetti e non comprendono perché le due date siano identiche (se poi modifico una anche l’altra sarà modificata.
Altro problema difficile da risolvere con l’oggetto Date è la gestione dei fusi orari. Se stiamo sviluppando un’applicazione che gestisce degli orari e questi devono essere inseriti o visualizzati in diversi fusi orari la cosa diventa abbastanza complicata (in Date abbiamo il valore GMTOffset ma questo non rispecchia la presenza o meno dell’ora legale) quindi la trasformazione da o in orario GMT è potenzialmente non corretta.
Ultimo problema la visualizzazione della data: se vogliamo mostrare la data localizzata in modo diverso da quello di sistema dobbiamo creare delle funzioni apposite in quanto i vari metodi: LongDate, Abbreviated date etc. rappresentano la data nel formato corrente.
Utilizziamo il nuovo Framework
L’oggetto data nel nuovo Framework di Xojo risolve questi problemi.
L’oggetto è immutabile.
Non possiamo modificarne le parti, le possiamo interrogare ma non modificare. Per modificarle dobbiamo utilizzare l’oggetto DateInterval che permette di definire la quantità di tempo che vogliamo aggiungere o sottrarre alla data per ottenerne una nuova.
Ad esempio la funzione per ottenere l’ultimo giorno del mese sarà:
Function fineMese(dataCorrente as Xojo.Core.Date) as Xojo.Core.Date Dim intervallo as New Xojo.Core.DateInterval(0, 1) //possiamo creare il nuovo intervallo come sequenza di elementi Dim nuovaData as Xojo.Core.Date=dataCorrente+intervallo intervallo=new Xojo.Core.DateInterval intervallo.Day=nuovaData.Day //possiamo crearlo vuoto e impostare singolarmente i singoli parametri nuovaData=nuovaData-intervallo return nuovaData End Function //Utilizziamo la funzione Dim giorno as new Xojo.Core.Date(2017, 2, 25, Xojo.Core.TimeZone.Current) //Creiamo la data con i parametri e il fuso corrente dim ultimo as Xojo.Core.Date=fineMese(giorno) //I due oggetti sono diversi e giorno rappresenta ancora la data di partenza |
Con il nuovo Framework abbiamo a disposizione i fusi orari
La data di Xojo.Core.Date ha sempre il fuso orario per cui se vogliamo avere la data relativa al GMT possiamo scrivere nel nostro arsenale dei metodi comuni:
Public Function toGMT(extends dataOriginale as Xojo.Core.Date) as Xojo.Core.Date Dim GMTZone As New Xojo.Core.TimeZone("GMT") Dim GMTDate As New Xojo.Core.Date(dataOriginale.SecondsFrom1970, GMTZone) Return GMTDate End Function Public Function fromGMT(extends gmtDate as Xojo.Core.Date) as Xojo.Core.Date Dim dataLocale As New xojo.Core.Date(gmtDate.SecondsFrom1970, Xojo.Core.TimeZone.Current) Return dataLocale End Function //Utilizziamo queste funzioni con date vicine al passaggio tra ora solare e legale //Nel 2017 il passaggio è tra il 28 e il 29 ottobre 2017 Dim dataOriginale As Xojo.Core.Date=Xojo.Core.Date.FromText("2017-10-28 12:00:00") //dataOriginale ora è 2017-10-28 12:00:00 Dim gmtDate As Xojo.Core.Date=dataOriginale.toGMT //gmtDate ora è 2017-10-28 10:00:00 dim cetDate as Xojo.Core.Date=gmtDate.fromGMT //cetDate ora è 2017-10-28 12:00:00 //Passiamo al giorno successivo Dim dt As New Xojo.Core.DateInterval dt.Days=1 dataOriginale=dataOriginale+dt //dataOriginale ora è 2017-10-29 12:00:00 gmtDate=dataOriginale.toGMT //gmtDate ora è 2017-10-29 11:00:00 cetDate=gmtDate.fromGMT //cetDate ora è 2017-10-29 12:00:00 |
Con il nuovo Framework abbiamo a disposizione una localizzazione completa
L’oggetto Xojo.Core.Date può mostrare la data in diversi formati locali e non solo in quello corrente del sistema operativo e questo è estremamente utile specialmente nelle applicazioni XojoWeb dove la localizzazione la dovrebbe decidere il client che si connette.
//Impostiamo una data del Framework classico corrispondete all'ultima dataOriginale utilizzata Dim d As New date d.SQLDateTime=dataOriginale.ToText //.ToText senza parametri è l'equivalente di .SQLDateTime del Framework classico //Mostriamo la data sia in italiano che in tedesco grazie al nuovo framework //Data breve System.DebugLog d.AbbreviatedDate //Otteniamo 29 ott 2017 System.DebugLog dataOriginale.ToText(Xojo.Core.Locale.Current, Xojo.Core.Date.FormatStyles.Medium, Xojo.Core.Date.FormatStyles.None) //Otteniamo 29 ott 2017 System.DebugLog dataOriginale.ToText(New Xojo.Core.Locale("DE-de"), Xojo.Core.Date.FormatStyles.Medium, Xojo.Core.Date.FormatStyles.None) //Otteniamo 29.10.2017 //Formato completo //Per il framework classico usiamo lo spazio ma non è detto //che sia il separatore corretto tra la parte data e quella tempo System.DebugLog d.LongDate+" "+d.LongTime //Otteniamo domenica 29 ottobre 2017 12:00:00 System.DebugLog dataOriginale.ToText(Xojo.Core.Locale.Current, Xojo.Core.Date.FormatStyles.Full, Xojo.Core.Date.FormatStyles.Full) //Otteniamo domenica 29 ottobre 2017 12:00:00 Ora standard dell’Europa centrale System.DebugLog dataOriginale.ToText(New Xojo.Core.Locale("DE-de"), Xojo.Core.Date.FormatStyles.Full, Xojo.Core.Date.FormatStyles.Full) //Otteniamo Sonntag, 29. Oktober 2017 um 12:00:00 Mitteleuropäische Normalzeit |
Questo è utile anche nella lettura delle date, prima eravamo vincolati al solo formato corrente ora possiamo anche ottenere:
Dim xGer As Xojo.Core.Date=Xojo.Core.Date.FromText( _ "Sonntag, 29. Oktober 2017 um 12:00:00 Mitteleuropäische Normalzeit", _ New Xojo.Core.Locale("DE-de") _ ) |
Ovvero possiamo leggere date in formati complessi anche da altre lingue, posto di identificare la corretta Locale.
Devo sempre utilizzare Xojo.Core…?
Se il mio codice è sempre relativo al nuovo framework posso scrivere all’inizio
Using Xojo.Core Dim xGer As Date=Date.FromText( _ "Sonntag, 29. Oktober 2017 um 12:00:00 Mitteleuropäische Normalzeit", _ New Locale("DE-de") _ ) |
Ma considerando che possiamo utilizzare entrambi i Framework e che sia a disposizione il completamento automatico, non è un gran problema scrivere la forma completa anche per chiarezza del proprio sorgente.