Rutas
/
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, dos de las cuales se tratarán aquí.

  • El tiempo universal es un tiempo absoluto, un número entero que representa el número 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 concreto del calendario: segundos, minutos, hora, día del mes, mes, año, día de la semana, indicador de horario de verano y zona horaria. (Se explica en detalle más abajo.)

Tiempo universal

Para obtener el tiempo universal actual se usa get-universal-time o get-decoded-time. La primera devuelve los segundos actuales desde 1900-01-01T00:00Z y la segunda devuelve esos 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 tiempo decodificado como múltiples valores, y la segunda toma los valores de tiempo decodificado como argumentos y devuelve un tiempo universal.

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

Un tiempo decodificado es un conjunto de valores:

  • segundos: un número entero entre 0 y 59
  • minutos: un número entero entre 0 y 59
  • hora: un número entero entre 0 y 23
  • día del mes: un número entero entre 1 y 31 (obviamente, el límite superior depende del mes y del año)
  • mes: un número entero entre 1 y 12
  • año: un número entero que indica el año.
  • día de la semana: un número 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 vigor.
  • 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 interesa el primer valor, no hace falta 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 tendrás que usar. Las dos macros principales son multiple-value-list y multiple-value-bind. 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 a cada uno de los valores.

(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 gigasegundo. Es decir: 1.000.000.000 segundos desde el acontecimiento.

1. Calcula la fecha del aniversario del gigasegundo

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

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

¿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.