Trilhas
/
Elixir
Elixir
/
Exercícios
/
Taxas da biblioteca
Taxas da biblioteca

Taxas da biblioteca

Exercício de aprendizagem

Introdução

Datas e horas

A biblioteca padrão do Elixir oferece 4 módulos diferentes para trabalhar com datas e horas, cada um com seu próprio struct.

  • O módulo Date. Um struct Date pode ser criado com o sigilo ~D.

    ~D[2021-01-01]
    
  • O módulo Time. Um struct Time pode ser criado com o sigilo ~T.

    ~T[12:00:00]
    
  • O módulo NaiveDateTime para datas e horas sem fuso horário. Um struct NaiveDateTime pode ser criado com o sigilo ~N.

    ~N[2021-01-01 12:00:00]
    
  • O módulo DateTime para datas e horas com fuso horário. Usar esse módulo para fusos horários diferentes de UTC exige uma dependência externa, um banco de dados de fusos horários.

Comparações

Para comparar datas ou horas entre si, procure uma função compare ou diff no módulo correspondente. Operadores de comparação como ==, > e < parecem funcionar, mas não fazem uma comparação semântica correta para esses structs.

Instruções

Sua amiga bibliotecária pediu que você estendesse o software da biblioteca dela para calcular automaticamente as taxas de atraso. O sistema atual dela armazena a data e a hora exatas da retirada de um livro como uma string de data e hora ISO8601. Ela administra uma biblioteca local em uma cidade pequena de Gana, que usa o fuso horário GMT (UTC +0), não adota horário de verão e não precisa se preocupar com outros fusos horários.

1. Fazer o parse das datas armazenadas

Implemente a função LibraryFees.datetime_from_string/1. Ela deve receber uma string de data e hora ISO8601 como argumento e retornar uma struct NaiveDateTime.

LibraryFees.datetime_from_string("2021-01-01T13:30:45Z")
# => ~N[2021-01-01 13:30:45]

2. Determinar se um livro foi retirado antes do meio-dia

Se um livro foi retirado antes do meio-dia, o leitor tem 28 dias para devolvê-lo. Se foi retirado ao meio-dia ou depois, são 29 dias.

Implemente a função LibraryFees.before_noon?/1. Ela deve receber uma struct NaiveDateTime e retornar um valor booleano.

LibraryFees.before_noon?(~N[2021-01-12 08:23:03])
# => true

3. Calcular a data de devolução

Com base na data e hora da retirada, calcule a data de devolução.

Implemente a função LibraryFees.return_date/1. Ela deve receber uma struct NaiveDateTime e retornar uma struct Date, 28 ou 29 dias depois.

LibraryFees.return_date(~N[2020-11-28 15:55:33])
# => ~D[2020-12-27]

4. Determinar o atraso na devolução do livro

A biblioteca cobra uma taxa fixa por devoluções atrasadas. Para calcular a taxa, precisamos saber quantos dias após a data de devolução o livro foi realmente devolvido.

Implemente a função LibraryFees.days_late/2. Ela deve receber uma struct Date (a data de devolução planejada) e uma struct NaiveDateTime (a data e hora da devolução real).

Se a data de devolução real for em um dia anterior ou no mesmo dia que a data e hora da devolução planejada, a função deve retornar 0. Caso contrário, ela deve retornar a diferença entre essas duas datas em dias.

A biblioteca registra tanto a data quanto a hora da devolução real do livro para fins estatísticos, mas não usa a hora no cálculo da taxa de atraso.

LibraryFees.days_late(~D[2020-12-27], ~N[2021-01-03 09:23:36])
# => 7

5. Determinar se o livro foi devolvido em uma segunda-feira

A biblioteca tem uma oferta especial para devoluções de livros às segundas-feiras.

Implemente a função LibraryFees.monday?/1. Ela deve receber uma struct NaiveDateTime e retornar um valor booleano.

LibraryFees.monday?(~N[2021-01-03 13:30:45Z])
# => false

6. Calcular a taxa de atraso

Implemente a função LibraryFees.calculate_late_fee/3. Ela deve receber três argumentos: duas strings de data e hora ISO8601 (a data e hora da retirada e a data e hora da devolução real) e a taxa de atraso de um dia. Ela deve retornar a taxa de atraso total de acordo com o atraso da devolução real do livro.

Inclua a oferta especial de segunda-feira. Se você devolver o livro em uma segunda-feira, sua taxa de atraso tem 50% de desconto, arredondado para baixo.

# Sunday, 7 days late
LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-03T13:30:45Z", 100)
# => 700

# one day later, Monday, 8 days late
LibraryFees.calculate_late_fee("2020-11-28T15:55:33Z", "2021-01-04T09:02:11Z", 100)
# => 400
Editar via GitHub O link abre em uma nova janela ou aba
Elixir Exercism

Tudo pronto para começar Taxas da biblioteca?

Crie sua conta no Exercism para aprender e dominar Elixir com 58 conceitos168 exercícios e mentoria humana de verdade, tudo de graça.