«Date e orari sono cose che insegniamo ai bambini piccoli. Quanto può essere difficile?»
Molti programmatori hanno commesso questo errore, e l'esperienza che ne consegue tende ad avere un effetto negativo sulla loro salute e sulla loro felicità.
Chiunque faccia programmazione non banale con date e orari dovrebbe almeno essere pronto a capire e a mitigare i potenziali problemi.
Questo documento cercherà di dare una panoramica di come Julia gestisce date e orari, ma per maggiori dettagli sarà necessario consultare il manuale. C'è anche un Wikibook che alcuni lettori potrebbero trovare più chiaro nelle sue spiegazioni, e che include un utile diagramma della gerarchia dei tipi.
Dates
La maggior parte delle funzionalità di base si trova in Dates, un modulo incluso in un'installazione predefinita ma che non fa parte della libreria standard.
Per usare il modulo, ci sono due opzioni:
import Dates, poi anteponi Dates. a tutte le chiamate di funzione.using Dates, che porta l'intero modulo nello spazio dei nomi corrente (tranne alcuni nomi problematici).# option 1
julia> import Dates
julia> Dates.now()
2025-06-21T16:02:39.080
julia> now() # wrong: need to include `Dates.` after an import
ERROR: UndefVarError: `now` not defined in `Main`
# option 2
julia> using Dates
julia> now() # functions are now in the namespace
2025-06-21T16:03:04.161
Il modulo Dates è grande e complicato, ma fornisce quattro tipi principali di funzionalità:
Dates.Date, che comprende giorno, mese e anno ma non l'ora del giorno.Dates.Time, che comprende l'ora del giorno, ma non la data.Dates.DateTime, che combina data e ora.Dates.Period, che gestisce intervalli di tempo e di data.Tieni presente che un DateTime generalmente non include informazioni sul fuso orario (Python lo chiamerebbe un datetime «naive»).
Un'eccezione è now(), che prende l'ora locale dall'orologio di sistema e, se necessario, può convertirla in UTC.
Forse le esigenze più frequenti sono:
Dates.Dates.Date, Time o DateTime.today()) e/o l'ora (con now()).Per ridurre le distrazioni visive, la maggior parte del codice di esempio nel resto di questo documento presuppone using Dates ed evita di includere il nome del modulo Dates. nelle chiamate di funzione.
Ci sono molti modi per scrivere date e orari, che tendono a essere specifici di una cultura. Le date composte solo da numeri come «7/6/23» sono ambigue, confuse e hanno portato a molti errori costosi in organizzazioni multinazionali (l'autore lo dice per amara esperienza personale).
Lo standard internazionale è definito in ISO 8601, con due vantaggi principali:
Abbiamo visto in un esempio precedente che Date.now() restituiva 2025-06-21T16:03:04.161.
Questo è composto da varie parti:
YYYY-MM-DD per la parte della data.hh:mm:ss per la parte dell'ora.Altri formati di stringa saranno discussi in una sezione successiva.
Dates.Date è un tipo relativamente semplice, solo data, senza alcuna nozione di orari o fusi orari.
# constructor with year, month, day arguments
julia> date1 = Date(2025, 06, 23)
2025-06-23
# constructor with ISO 8601 string
julia> date2 = Date("2025-06-23")
2025-06-23
julia> date1 == date2
true
julia> typeof(date1)
Date
Esistono funzioni di accesso per le singole parti della data, e queste vengono in coppie distinte dall'uso di maiuscole e minuscole.
# lowercase returns an integer
julia> month(date1)
6
julia> typeof(month(date1))
Int64
# Propercase returns a Period type
julia> Month(date1)
6 months
julia> typeof(Month(date1))
Month
Esistono varie funzioni che hanno una certa comprensione del calendario. L'esempio seguente ne mostra solo alcune.
julia> date1
2025-06-23
julia> dayofweek(date1) # 1 = Monday, 7 = Sunday
1
julia> dayname(date1)
"Monday"
julia> daysinmonth(date1)
30
julia> isleapyear(date1)
false
julia> lastdayofmonth(date1)
2025-06-30
Dates.Time è il tipo di base che rappresenta solo l'ora.
Non ha alcuna nozione delle date: gli orari tornano automaticamente a Time(0, 0, 0) a mezzanotte.
Il formato completo del costruttore è Time(hour, min, sec, millisec, microsec) o l'equivalente ISO 8601.
Tutti i parametri sono facoltativi e hanno come valore predefinito 0.
julia> Time(14, 57, 25, 142)
14:57:25.142
julia> Time("14:57:25.142")
14:57:25.142
julia> Time(14, 57, 25, 142, 32)
14:57:25.142032
Come per Date, le singole parti sono disponibili tramite funzioni di accesso:
julia> minute(t) # => integer
57
julia> Minute(t) # => Period
57 minutes
Dates.DateTime combina la maggior parte delle caratteristiche dei tipi Date e Time.
julia> dt1 = DateTime(2025, 6, 23, 14, 57, 25, 142)
2025-06-23T14:57:25.142
# date1 and t were defined in previous examples
julia> dt2 = DateTime(date1, t)
2025-06-23T14:57:25.142
I parametri anno, mese e giorno hanno come valore predefinito 1, mentre tutti i parametri dell'ora hanno come valore predefinito 0.
Tenere a mente tutti questi parametri può essere complicato, quindi per l'input il formato ISO potrebbe essere preferibile.
In alternativa, un DateTime può essere costruito a partire da una Date e una Time, come nell'esempio precedente.
Ognuna delle componenti di data e ora ha il proprio tipo Period, da Year fino a Nanosecond, che rappresenta un intervallo di tempo.
Sono particolarmente utili per l'aritmetica.
julia> dt1
2025-06-23T14:57:25.142
julia> Year(21)
21 years
julia> Second(61)
61 seconds
julia> dt1 + Year(21) - Second(61)
2046-06-23T14:56:24.142
julia> Date(2025, 07, 03) - Date(2025, 04, 25)
69 days
Quando si lavora con i tipi Period, Julia cerca di gestire in modo intelligente le irregolarità del calendario, come la lunghezza dei mesi, arrotondando dove necessario.
# February has fewer days than January
julia> Date(2025, 1, 31) + Month(1)
2025-02-28
Abbiamo già citato lo standard ISO 8601, che è la rappresentazione predefinita di data e ora di Julia quando formatta o analizza le stringhe.
Ovviamente, molti altri formati sono di uso frequente, spesso in modi specifici di una cultura.
Per gestirli, Julia dispone del tipo DateFormat, che può essere costruito a partire da una stringa di formato di complessità arbitraria.
# dateformat"" string syntax
julia> dtfmt = dateformat"d/m/y"
dateformat"d/m/y"
julia> typeof(dtfmt)
DateFormat{Symbol("d/m/y"), Tuple{Dates.DatePart{'d'}, Dates.Delim{Char, 1}, Dates.DatePart{'m'}, Dates.Delim{Char, 1}, Dates.DatePart{'y'}}}
# DateFormat constructor
julia> DateFormat("d/m/y")
dateformat"d/m/y"
L'esempio precedente è molto semplice, solo una data nel formato giorno/mese/anno comune in Europa. Vengono mostrate due varianti della sintassi, ma il risultato è identico.
Un DateFormat può poi essere usato per analizzare qualsiasi stringa adatta:
julia> DateTime("14/7/2023", dtfmt)
2023-07-14T00:00:00
Creare un DateFormat comporta un sovraccarico significativo, quindi eseguire questo passaggio una sola volta (come qui con dtfmt) è utile per le prestazioni quando si itera su molte stringhe di data e ora.
I formati possono essere molto più complessi di così, quindi consulta il manuale per i dettagli.
Lo stesso DateFormat può anche essere usato per produrre una data e un'ora in qualsiasi formato di stringa desiderato, usando la funzione Dates.format().
Purtroppo sembra esserci un conflitto di spazio dei nomi con format (almeno a partire da Julia 1.11.5), quindi è meglio includere il prefisso Dates. anche dopo using Dates.
julia> dt1
2025-06-23T14:57:25.142
julia> Dates.format(dt1, dateformat"e, u d")
"Mon, Jun 23"
Come documentato, "e, u d" fornisce la rappresentazione testuale abbreviata per il giorno della settimana e il mese.
La rappresentazione testuale è in inglese per impostazione predefinita. Si possono aggiungere altre lingue, anche se attualmente il supporto è subottimale.
In questo esercizio lavorerai a un sistema di pianificazione degli appuntamenti per un salone di bellezza a New York che ha aperto il 15 settembre 2012.
Hai cinque attività, che avranno tutte a che fare con le date degli appuntamenti. Gli orari sono in formato 24 ore (niente AM/PM).
Implementa la funzione schedule_appointment() per analizzare una rappresentazione testuale della data di un appuntamento e convertirla nel formato DateTime corrispondente.
Nota che l'input segue l'ordine mese/giorno/anno in stile statunitense.
julia> schedule_appointment("07/25/2023 13:45:00")
2023-07-25T13:45:00
Implementa la funzione has_passed() che prende una data di appuntamento e controlla se l'appuntamento si trova nel passato:
julia> has_passed(DateTime(1999, 12, 31, 9, 0, 0))
true
Implementa la funzione is_afternoon_appointment() che prende una data di appuntamento e controlla se l'appuntamento è nel pomeriggio (>= 12:00 e < 18:00):
julia> is_afternoon_appointment(DateTime(2023, 3, 29, 15, 0, 0))
true
Implementa la funzione description() che prende una data di appuntamento e restituisce una descrizione di quella data e ora:
julia> describe(DateTime(2023, 3, 29, 15, 0, 0))
"You have an appointment on Wednesday, March 29, 2023 at 15:00"
Implementa la funzione anniversary_date() che restituisce la data dell'anniversario di quest'anno, cioè il 15 settembre:
julia> anniversary_date() # run during 2025
2025-09-15
Iscriviti a Exercism per imparare e padroneggiare Julia con 35 concetti128 esercizi e il mentoring di persone reali, tutto gratis.