Tracks
/
Common Lisp
Common Lisp
/
Ejercicios
/
Aniversario del gigasegundo
Aniversario del gigasegundo

Aniversario del gigasegundo

Ejercicio de aprendizaje

Introducción

Fecha y hora

En Common Lisp, el tiempo se representa de cuatro maneras; aquí veremos dos de ellas.

  • El tiempo universal es un tiempo absoluto: un entero que representa la cantidad de segundos transcurridos desde 1900-01-01T00:00:00Z (es decir, la medianoche del 1 de enero de 1900 en UTC).
  • El tiempo decodificado es una tupla de 9 valores que, en conjunto, representan un momento específico del calendario: segundos, minutos, hora, día del mes, mes, año, día de la semana, indicador de horario de verano, zona horaria. (Se explican en detalle más abajo.)

Tiempo universal

Para obtener el tiempo universal actual se usa get-universal-time o get-decoded-time. El primero devuelve los segundos actuales desde 1900-01-01T00:00Z y el segundo devuelve los mismos datos en formato decodificado.

Tiempo decodificado

decode-universal-time y encode-universal-time son las funciones principales para trabajar con el tiempo. La primera toma un tiempo universal y devuelve un valor de tiempo decodificado en forma de múltiples valores, y la segunda toma los valores de tiempo decodificado como argumentos y devuelve un tiempo universal.

Ambas toman un argumento opcional de zona horaria. Más abajo se muestra el formato de la zona horaria.

Un tiempo decodificado es un conjunto de valores:

  • segundos: un entero entre 0 y 59
  • minutos: un entero entre 0 y 59
  • hora: un entero entre 0 y 23
  • día del mes: un entero entre 1 y 31 (el límite superior en realidad depende del mes y del año, obviamente)
  • mes: un entero entre 1 y 12
  • año: un entero que indica el año.
  • día de la semana: un entero entre 0 y 6. 0 significa lunes, 1 significa martes, etc. ... 6 significa domingo.
  • indicador de horario de verano: un valor verdadero indica que el horario de verano está en efecto.
  • zona horaria: un número de horas entre -24 y 24 que indica el desplazamiento respecto a UTC. El número es un número racional y debe ser 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últiples valores

En Common Lisp, una función no solo puede devolver un valor, sino que puede devolver múltiples valores. Por ejemplo, floor, que redondea hacia cero, devuelve dos valores: el primero es el valor redondeado y el segundo es el residuo.

(floor 3.5) ; => 3
            ;    0.5

(Mostraremos los múltiples valores devueltos en líneas separadas de la salida.)

Devolver múltiples valores

Si quieres que una función devuelva múltiples valores, usas el accesor values:

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

Manejar múltiples valores

Si solo te importa el primer valor, no hay que hacer nada especial: el lenguaje se encarga de ello:

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

Sin embargo, si quieres acceder a esos otros valores, hay varias funciones que necesitarás usar. Las dos macros principales son multiple-value-list y multiple-value-bind. Estas se usan para envolver algo que devuelve múltiples valores y capturar todos los valores. La primera crea una lista con todos los valores. La segunda te permite vincular variables con los valores individuales.

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

Otra función útil es nth-value

Instrucciones

A los alienígenas de Lisp les gusta celebrar aniversarios. Para ellos, una fecha de aniversario importante es el Gigasecond. Es decir: 1,000,000,000 de segundos desde el evento.

1. Calcula la fecha del aniversario de Gigasecond

Escribe una función from que reciba 6 parámetros: year, month, day, hour, min, sec, y calcule la fecha y la hora del aniversario de Gigasecond. Esta función debe devolver la fecha como una lista con el mismo orden y el mismo significado que los parámetros que recibe.

(from 2000 1 1 0 0 0) ; => (2031 9 9 1 46 40)
Editar en GitHub El enlace se abre en una ventana o una pestaña nuevas
Common Lisp Exercism

¿Todo listo para empezar Aniversario del gigasegundo?

Regístrate en Exercism para aprender y dominar Common Lisp con 27 conceptos92 ejercicios y mentoría humana real, todo gratis.