Percursos
/
Common Lisp
Common Lisp
/
Exercícios
/
Aniversário de um gigasegundo
Aniversário de um gigasegundo

Aniversário de um gigasegundo

Exercício de aprendizagem

Introdução

Data e hora

Em Common Lisp, o tempo é representado de quatro formas, duas das quais vamos abordar aqui.

  • O tempo universal é um tempo absoluto, um número inteiro que representa o número de segundos desde 1900-01-01T00:00:00Z (ou seja, a meia-noite de 1 de janeiro de 1900 em UTC).
  • O tempo descodificado é um tuplo de 9 valores que, em conjunto, representam um momento específico do calendário: segundos, minutos, hora, dia do mês, mês, ano, dia da semana, indicador de hora de verão, fuso horário. (Analisado em detalhe abaixo.)

Tempo universal

Para obter o tempo universal atual, usa-se get-universal-time ou get-decoded-time. O primeiro devolve os segundos atuais desde 1900-01-01T00:00Z e o segundo devolve os mesmos dados em formato descodificado.

Tempo descodificado

decode-universal-time e encode-universal-time são as funções principais para trabalhar com o tempo. A primeira recebe um tempo universal e devolve um valor de tempo descodificado como múltiplos valores, e a segunda recebe os valores de tempo descodificado como argumentos e devolve um tempo universal.

Ambas recebem um argumento opcional de fuso horário. Vê abaixo o formato do fuso horário.

Um tempo descodificado é um conjunto de valores:

  • segundos: um número inteiro entre 0 e 59
  • minutos: um número inteiro entre 0 e 59
  • hora: um número inteiro entre 0 e 23
  • dia do mês: um número inteiro entre 1 e 31 (o limite superior depende, obviamente, do mês e do ano)
  • mês: um número inteiro entre 1 e 12
  • ano: um número inteiro que indica o ano.
  • dia da semana: um número inteiro entre 0 e 6. 0 significa segunda-feira, 1 significa terça-feira, etc. ... 6 significa domingo.
  • indicador de hora de verão: um valor verdadeiro indica que a hora de verão está em vigor.
  • fuso horário: um número de horas entre -24 e 24 que indica o desvio em relação a UTC. O número é um número racional e tem de ser um múltiplo de 1/3600
(encode-universal-time 1 2 3 4 5 2000 0) ; => 3166398121
(decode-universal-time 3166398121)       ; => 1
                                         ;    2
                                         ;    3
                                         ;    4
                                         ;    5
                                         ;    2000
                                         ;    3 (Thursday)
                                         ;    NIL
                                         ;    0
(decode-universal-time 2208988800) ; => 0
                                   ;    0
                                   ;    0
                                   ;    1
                                   ;    1
                                   ;    1970
                                   ;    3
                                   ;    NIL
                                   ;    0

Múltiplos valores

Em Common Lisp, uma função não só pode devolver um valor como pode devolver vários valores. Por exemplo, floor, que arredonda para baixo em direção ao zero, devolve dois valores: o primeiro é o valor arredondado e o segundo é o resto.

(floor 3.5) ; => 3
            ;    0.5

(Vamos mostrar os múltiplos valores devolvidos em linhas separadas da saída.)

Devolver múltiplos valores

Se queres que uma função devolva múltiplos valores, usas o acessor values:

(defun three-numbers () (values 1 2 3))
(three-numbers) ; => 1
                ;    2
                ;    3

Lidar com múltiplos valores

Se só te interessa o primeiro valor, não é preciso fazer nada de especial, porque a linguagem trata disso:

(+ (values 1 2 3) (values 10 20 30)) ; => 11

No entanto, se quiseres aceder a esses outros valores, há várias funções que vais precisar de usar. Há duas macros principais: multiple-value-list e multiple-value-bind. São usadas para envolver algo que devolve múltiplos valores e captam todos os valores. A primeira cria uma lista com todos os valores. A segunda permite-te ligar variáveis aos valores individuais.

(multiple-value-list (values 1 2 3))                   ; => (1 2 3)
(multiple-value-bind (a b c) (values 1 2 3) 
   (+ a b c)) ; => 6

Outra função útil é nth-value

Instruções

Os Lisp Aliens gostam de celebrar aniversários. Para eles, uma data de aniversário importante é o gigasegundo. Ou seja: 1 000 000 000 segundos desde o evento.

1. Calcula a data de aniversário do gigasegundo

Escreve uma função from que recebe 6 parâmetros: year, month, day, hour, min, sec e calcula a data e a hora do aniversário do gigasegundo. Esta função deve devolver a data numa lista com a mesma ordem e o mesmo significado dos parâmetros que recebe.

(from 2000 1 1 0 0 0) ; => (2031 9 9 1 46 40)
Editar via GitHub A ligação abre numa nova janela ou separador
Common Lisp Exercism

Estás pronto para começar Aniversário de um gigasegundo?

Inscreve-te no Exercism para aprenderes e dominares Common Lisp com 27 conceitos92 exercícios, e mentoria humana real, tudo grátis.