Skip to content

Utilizzare le date nel nuovo Framework di Xojo

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.