"Datas e horas são algo que ensinamos a crianças pequenas. Quão difícil pode ser?"
Muitos programadores já cometeram esse erro, e a experiência que se segue costuma ter um efeito negativo na sua saúde e felicidade.
Quem faz programação não trivial com datas e horas deve, no mínimo, estar preparado para compreender e mitigar potenciais problemas.
Este documento procura dar uma visão geral de como a Julia trata datas e horas, mas será necessário consultar o manual para mais detalhes. Há também um Wikibook cujas explicações alguns leitores podem achar mais claras, e que inclui um diagrama útil da hierarquia de tipos.
Dates
A maior parte da funcionalidade básica está em Dates, um módulo incluído numa instalação padrão, mas que não faz parte da biblioteca padrão.
Para usar o módulo, há duas opções:
import Dates e depois preceder todas as chamadas de funções com Dates.
using Dates, o que traz todo o módulo para o espaço de nomes atual (exceto alguns nomes problemáticos).# 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
O módulo Dates é grande e complicado, mas fornece quatro tipos principais de funcionalidade:
Dates.Date, que inclui dia, mês e ano, mas não a hora do dia.Dates.Time, que inclui a hora do dia, mas não a data.Dates.DateTime, que combina data e hora.Dates.Period, que trata intervalos de tempo/data.Repara que um DateTime geralmente não inclui informação de fuso horário (o Python chamaria a isto um datetime "naive").
Uma exceção é now(), que obtém a hora local do relógio do teu sistema e que a pode converter para UTC, se for necessário.
Talvez as necessidades mais frequentes sejam:
Dates.Dates.Date, Time ou DateTime.today()) e/ou a hora (com now()).Para reduzir a distração visual, a maior parte do código de exemplo no resto deste documento assume using Dates e evita incluir o nome do módulo Dates. nas chamadas de funções.
Há muitas formas de escrever datas e horas, que tendem a ser específicas de cada cultura. As datas só com números, como "7/6/23", são ambíguas e confusas, e já levaram a muitos erros dispendiosos em organizações multinacionais (o autor fala por amarga experiência pessoal).
O padrão internacional está definido na ISO 8601 e tem duas vantagens principais:
Vimos num exemplo anterior que Date.now() devolvia 2025-06-21T16:03:04.161.
Isto é composto por várias partes:
YYYY-MM-DD para a parte da data.hh:mm:ss para a parte da hora.Outros formatos de string serão abordados numa secção posterior.
Dates.Date é um tipo relativamente simples, só de data, sem qualquer compreensão de horas ou fusos horários.
# 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
Há funções de acesso para as partes individuais da data, e estas formam pares que se distinguem pelo uso de minúsculas ou maiúsculas.
# 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
Há uma variedade de funções com alguma compreensão do calendário. O exemplo seguinte mostra apenas algumas.
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 é o tipo básico só de hora.
Não tem qualquer compreensão de datas: as horas passam automaticamente para Time(0, 0, 0) à meia-noite.
O formato completo do construtor é Time(hour, min, sec, millisec, microsec) ou o equivalente em ISO 8601.
Todos os parâmetros são opcionais e assumem 0 por omissão.
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
Tal como com Date, as partes individuais estão disponíveis através de funções de acesso:
julia> minute(t) # => integer
57
julia> Minute(t) # => Period
57 minutes
Dates.DateTime combina a maior parte das características dos tipos 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
Os parâmetros de ano, mês e dia assumem 1 por omissão, e os parâmetros de hora assumem todos 0 por omissão.
Manter todos estes parâmetros na ordem certa pode ser um desafio, por isso o formato ISO pode ser preferível para a entrada.
Em alternativa, um DateTime pode ser construído a partir de um Date e um Time, como no exemplo acima.
Cada um dos componentes de data/hora tem o seu próprio tipo Period, desde Year até Nanosecond, que representa um intervalo de tempo.
Estes são particularmente úteis para a aritmética.
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
Ao trabalhar com tipos Period, a Julia tenta ser inteligente em relação a irregularidades do calendário, como a duração dos meses, arredondando quando é necessário.
# February has fewer days than January
julia> Date(2025, 1, 31) + Month(1)
2025-02-28
Já mencionámos o padrão ISO 8601, que é a representação de data/hora predefinida da Julia ao formatar ou analisar strings.
Obviamente, muitos outros formatos são usados com frequência, muitas vezes de formas específicas de cada cultura.
Para os tratar, a Julia tem o tipo DateFormat, que pode ser construído a partir de uma string de formato com a complexidade que se quiser.
# 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"
O exemplo acima é muito simples: apenas uma data no formato dia/mês/ano comum na Europa. São mostradas duas variantes da sintaxe, mas o resultado é idêntico.
Um DateFormat pode depois ser usado para analisar qualquer string adequada:
julia> DateTime("14/7/2023", dtfmt)
2023-07-14T00:00:00
Criar um DateFormat envolve um custo significativo, por isso fazer este passo apenas uma vez (como aqui com dtfmt) ajuda no desempenho quando se percorrem muitas strings de data/hora.
Os formatos podem ser muito mais complexos do que isto, por isso consulta o manual para mais detalhes.
O mesmo DateFormat também pode ser usado para produzir uma data/hora em qualquer formato de string desejado, com a função Dates.format().
Infelizmente, parece haver um conflito de espaço de nomes com format (pelo menos na versão 1.11.5 da Julia), por isso é melhor incluir o prefixo Dates. mesmo depois de using Dates.
julia> dt1
2025-06-23T14:57:25.142
julia> Dates.format(dt1, dateformat"e, u d")
"Mon, Jun 23"
Como está documentado, "e, u d" dá a representação textual abreviada do dia da semana e do mês.
A representação textual assume o inglês por omissão. Podem ser adicionadas outras línguas, embora o suporte para isso seja atualmente pouco satisfatório.
Neste exercício vais trabalhar num agendador de marcações para um salão de beleza em Nova Iorque que abriu a 15 de setembro de 2012.
Tens cinco tarefas, todas relacionadas com datas de marcação. Os horários estão no formato de 24 horas (sem AM/PM).
Implementa a função schedule_appointment() para converter uma representação textual de uma data de marcação no formato DateTime correspondente.
Repara que o valor de entrada está no formato dos Estados Unidos: mês/dia/ano.
julia> schedule_appointment("07/25/2023 13:45:00")
2023-07-25T13:45:00
Implementa a função has_passed(), que recebe uma data de marcação e verifica se a marcação já passou:
julia> has_passed(DateTime(1999, 12, 31, 9, 0, 0))
true
Implementa a função is_afternoon_appointment(), que recebe uma data de marcação e verifica se a marcação é à tarde (>= 12:00 e < 18:00):
julia> is_afternoon_appointment(DateTime(2023, 3, 29, 15, 0, 0))
true
Implementa a função description(), que recebe uma data de marcação e devolve uma descrição dessa data e hora:
julia> describe(DateTime(2023, 3, 29, 15, 0, 0))
"You have an appointment on Wednesday, March 29, 2023 at 15:00"
Implementa a função anniversary_date(), que devolve a data de aniversário deste ano, que é 15 de setembro:
julia> anniversary_date() # run during 2025
2025-09-15
Inscreve-te no Exercism para aprenderes e dominares Julia com 35 conceitos128 exercícios, e mentoria humana real, tudo grátis.