Data e Tempo
Trabalhando com tempo em Elixir.
Time
O Elixir tem alguns módulos que trabalham com tempo. Ainda que precise ser notado que essa funcionalidade é limitada para trabalhar com fuso horário UTC.
Vamos começar pegando o tempo atual:
iex> Time.utc_now
~T[19:39:31.056226]
Note que nós vamos ter um sigil que pode ser usado para criar uma struct Time
também:
iex> ~T[19:39:31.056226]
~T[19:39:31.056226]
Você pode aprender mais sobre sigil na lição sobre sigils. É fácil acessar partes desta struct:
iex> t = ~T[19:39:31.056226]
~T[19:39:31.056226]
iex> t.hour
19
iex> t.minute
39
iex> t.day
** (KeyError) key :day not found in: ~T[19:39:31.056226]
Mas há uma pegadinha: como você pode ter notado, essa struct contém apenas tempo de um dia, dados de dia/mês/ano não estão presentes.
Date
Ao contrário do Time
, a struct Date
tem as informações sobre a data sem nenhuma informação sobre o tempo.
iex> Date.utc_today
~D[2028-10-21]
Mas ele tem algumas funções úteis para trabalhar com datas:
iex> {:ok, date} = Date.new(2020, 12, 12)
{:ok, ~D[2020-12-12]}
iex> Date.day_of_week date
6
iex> Date.leap_year? date
true
day_of_week/1
calcula em que dia da semana será a data provida.
Nesse caso é um sábado.
leap_year?/1
verifica se é um ano bissexto.
Outras funções podem ser encontradas na documentação.
NaiveDateTime
Há dois tipos de structs que contém tanto a data e o tempo em apenas um lugar no Elixir.
O primeiro dos dois é o NaiveDateTime
.
A desvantagem é a falta de suporte para fuso horário:
iex> NaiveDateTime.utc_now
~N[2022-01-21 19:55:10.008965]
Mas ele tem tanto o tempo como a data, então você pode adicionar tempo, por exemplo:
iex> NaiveDateTime.add(~N[2018-10-01 00:00:14], 30)
~N[2018-10-01 00:00:44]
DateTime
O segundo, como você pode ter adivinhado a partir do título dessa seção, é DateTime
.
Não possui as limitações mencionadas no NaiveDateTime
: possui data e hora e suporta fusos horários.
Mas esteja ciente dos fusos horários. A documentação oficial fala:
Muitas funções neste módulo requerem um fuso horário do banco de dados. Por padrão, é utilizado o fuso horário do banco de dados que é retornado pela função
Calendar.get_time_zone_database/0
, cujo padrão éCalendar.UTCOnlyTimeZoneDatabase
, que lida apenas com as datas “Etc/UTC” e retorna{:error, :utc_only_time_zone_database}
para qualquer outro fuso horário.
Também, note que você pode criar um instância de DateTime a partir de um NaiveDateTime, apenas fornecendo o fuso horário:
iex> DateTime.from_naive(~N[2016-05-24 13:26:08.003], "Etc/UTC")
{:ok, #DateTime<2016-05-24 13:26:08.003Z>}
Trabalhando com timezones
Como observamos na seção anterior, por padrão, o Elixir não possui dados de fuso horário. Para resolver esse problema, precisamos instalar e configurar o pacote tzdata. Após a instalação, você deve configurar globalmente o Elixir para usar o Tzdata com o fuso horário do banco de dados:
config :elixir, :time_zone_database, Tzdata.TimeZoneDatabase
Agora, vamos tentar criar um horário no fuso horário de Paris e convertê-lo para o horário de Nova York:
iex> paris_datetime = DateTime.from_naive!(~N[2019-01-01 12:00:00], "Europe/Paris")
#DateTime<2019-01-01 12:00:00+01:00 CET Europe/Paris>
iex> {:ok, ny_datetime} = DateTime.shift_zone(paris_datetime, "America/New_York")
{:ok, #DateTime<2019-01-01 06:00:00-05:00 EST America/New_York>}
iex> ny_datetime
#DateTime<2019-01-01 06:00:00-05:00 EST America/New_York>
Como você pode ver, a hora mudou de 12:00 em Paris para às 6:00 em Nova York, o que é correto - a diferença no fuso horário entre as duas cidades é de 6 horas.
É isso! Se você quer trabalhar com outras funções avançadas, verifique na documentação de Time, Date, DateTime e NaiveDateTime Você pode considerar o Timex e Calendar que são bibliotecas poderosas para trabalhar com tempo no Elixir.
Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!