Треки
/
Common Lisp
Common Lisp
/
Вправи
/
Гігасекундна річниця
Гігасекундна річниця

Гігасекундна річниця

Навчальна вправа

Вступ

Дата і час

У Common Lisp час представляють чотирма способами, два з яких ми розглянемо тут.

  • Універсальний час - це абсолютний час, ціле число, що представляє кількість секунд від 1900-01-01T00:00:00Z (тобто опівночі 1 січня 1900 року за UTC).
  • Декодований час - це кортеж із 9 значень, які разом представляють конкретний календарний час: секунди, хвилини, годину, день місяця, місяць, рік, день тижня, прапорець літнього часу, часовий пояс. (Детально розглянуто нижче.)

Універсальний час

Щоб отримати поточний універсальний час, використовують get-universal-time або get-decoded-time. Перша повертає поточну кількість секунд від 1900-01-01T00:00Z, а друга повертає ті самі дані в декодованому форматі.

Декодований час

decode-universal-time та encode-universal-time - це основні функції для роботи з часом. Перша приймає універсальний час і повертає декодоване значення часу як множинні значення, а друга приймає декодовані значення часу як аргументи й повертає універсальний час.

Обидві приймають необовʼязковий аргумент часового поясу. Формат часового поясу описано нижче.

Декодований час - це набір значень:

  • секунди: ціле число від 0 до 59
  • хвилини: ціле число від 0 до 59
  • година: ціле число від 0 до 23
  • день місяця: ціле число від 1 до 31 (верхня межа насправді залежить від місяця й року, звісно)
  • місяць: ціле число від 1 до 12
  • рік: ціле число, що вказує рік.
  • день тижня: ціле число від 0 до 6. 0 означає понеділок, 1 означає вівторок тощо... 6 означає неділю.
  • прапорець літнього часу: значення «правда» вказує, що літній час діє.
  • часовий пояс: число годин від -24 до 24, що позначає зсув від UTC. Це число раціональне, і воно має бути кратним 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

Множинні значення

У Common Lisp функція може повертати не лише одне значення, а й кілька значень. Наприклад, floor, яка округлює вниз до нуля, повертає два значення: перше - округлене значення, а друге - остача.

(floor 3.5) ; => 3
            ;    0.5

(Ми будемо показувати кілька повернених значень на окремих рядках виводу.)

Повернення кількох значень

Якщо ми хочемо, щоб функція повертала кілька значень, ми використовуємо аксесор values:

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

Робота з кількома значеннями

Якщо нас цікавить лише перше значення, то нічого особливого робити не потрібно: мова подбає про це сама:

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

Однак якщо ми хочемо отримати доступ до тих інших значень, нам знадобиться кілька функцій. Дві основні макроси - це multiple-value-list і multiple-value-bind. Їх використовують, щоб обгорнути щось, що повертає кілька значень, і захопити всі ці значення. Перша створить масив з усіх значень. Друга дозволить привʼязати змінні до окремих значень.

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

Ще одна корисна функція - це nth-value

Вказівки

Lisp Aliens люблять святкувати ювілеї. Важливим ювілеєм для них є гігасекунда. Тобто 1 000 000 000 секунд від моменту події.

1. Обчислити дату ювілею гігасекунди

Напишіть функцію from, яка приймає 6 параметрів: year, month, day, hour, min, sec і обчислює дату й час ювілею гігасекунди. Ця функція повинна повернути дату у вигляді масиву в тому самому порядку й з тим самим змістом, що й параметри на вході.

(from 2000 1 1 0 0 0) ; => (2031 9 9 1 46 40)
Редагувати через GitHub Посилання відкривається в новому вікні або вкладці
Common Lisp Exercism

Час розпочати Гігасекундна річниця?

Зареєструйтеся на Exercism, щоб вивчати й опановувати Common Lisp, а також 27 концепцій92 вправи та справжнє наставництво від людей, і все це безкоштовно.