Track
/
Common Lisp
Common Lisp
/
Esercizi
/
Anniversario del gigasecondo
Anniversario del gigasecondo

Anniversario del gigasecondo

Esercizio di apprendimento

Introduzione

Data e ora

In Common Lisp il tempo è rappresentato in quattro modi; qui ne vedremo due.

  • Il tempo universale è un tempo assoluto, un numero intero che rappresenta il numero di secondi trascorsi da 1900-01-01T00:00:00Z (cioè la mezzanotte del 1º gennaio 1900 nel fuso UTC).
  • Il tempo decodificato è una tupla di 9 valori che, insieme, rappresentano un momento specifico del calendario: secondi, minuti, ora, giorno del mese, mese, anno, giorno della settimana, flag dell'ora legale, fuso orario. (Ne parleremo in dettaglio più avanti.)

Tempo universale

Per ottenere il tempo universale corrente si usano get-universal-time o get-decoded-time. Il primo restituisce i secondi correnti trascorsi da 1900-01-01T00:00Z, il secondo restituisce gli stessi dati in formato decodificato.

Tempo decodificato

decode-universal-time e encode-universal-time sono le funzioni principali per lavorare con il tempo. La prima prende un tempo universale e restituisce un tempo decodificato sotto forma di valori multipli, la seconda prende i valori del tempo decodificato come argomenti e restituisce un tempo universale.

Entrambe accettano un argomento opzionale per il fuso orario. Qui sotto trovi il formato del fuso orario.

Un tempo decodificato è un insieme di valori:

  • secondi: un numero intero tra 0 e 59
  • minuti: un numero intero tra 0 e 59
  • ora: un numero intero tra 0 e 23
  • giorno del mese: un numero intero tra 1 e 31 (il limite superiore dipende ovviamente dal mese e dall'anno)
  • mese: un numero intero tra 1 e 12
  • anno: un numero intero che indica l'anno.
  • giorno della settimana: un numero intero tra 0 e 6. 0 significa lunedì, 1 significa martedì ecc. ... 6 significa domenica.
  • flag dell'ora legale: un valore vero indica che l'ora legale è in vigore.
  • fuso orario: un numero di ore tra -24 e 24 che indica lo scostamento da UTC. Il numero è un numero razionale e deve essere un multiplo di 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

Valori multipli

In Common Lisp una funzione non solo può restituire un valore, ma può restituirne più di uno. Per esempio floor, che arrotonda verso il basso, restituisce due valori: il primo è il valore arrotondato e il secondo è il resto.

(floor 3.5) ; => 3
            ;    0.5

(Mostreremo i valori multipli restituiti su righe separate dell'output.)

Restituire più valori

Se vuoi che una funzione restituisca più valori, usi l'accessor values:

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

Gestire più valori

Se ti interessa solo il primo valore, non serve fare nulla di speciale: ci pensa il linguaggio:

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

Se invece vuoi accedere agli altri valori, dovrai usare diverse funzioni. Le due macro principali sono multiple-value-list e multiple-value-bind. Servono a racchiudere qualcosa che restituisce più valori e a catturarli tutti. La prima crea un array con tutti i valori. La seconda ti permette di associare le variabili ai singoli valori.

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

Un'altra funzione utile è nth-value

Istruzioni

Agli alieni Lisp piace celebrare gli anniversari. Per loro, un anniversario importante è il gigasecondo. Ovvero: 1.000.000.000 di secondi dall'evento.

1. Calcola la data dell'anniversario del gigasecondo

Scrivi una funzione from che prende 6 parametri: year, month, day, hour, min, sec e calcola la data e l'ora dell'anniversario del gigasecondo. Questa funzione dovrebbe restituire la data come un array nello stesso ordine e con lo stesso significato dei parametri di input.

(from 2000 1 1 0 0 0) ; => (2031 9 9 1 46 40)
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Common Lisp Exercism

Vuoi iniziare Anniversario del gigasecondo?

Iscriviti a Exercism per imparare e padroneggiare Common Lisp con 27 concetti92 esercizi e il mentoring di persone reali, tutto gratis.