Перейти до основного вмісту

Робота з датами та часом в Elixir

Elixir має вбудовані типи та модулі для роботи з датами, часом і часовими інтервалами. Основними модулями є Date, Time, NaiveDateTime, DateTime та Calendar.

Важливо розуміти різницю між ними. Date описує календарну дату, Time — час доби, NaiveDateTime — дату й час без інформації про часовий пояс, а DateTime — дату й час разом із часовим поясом.

У порівнянні з Java це приблизно відповідає класам LocalDate, LocalTime, LocalDateTime та ZonedDateTime з пакета java.time.

Дата за допомогою Date

Для представлення календарної дати використовується структура Date:

date = ~D[2026-08-21] date.year # 2026 date.month # 8 date.day # 21

Літерал ~D є sigil, спеціальним синтаксисом Elixir для створення дати.

Дата також може бути створена за допомогою функції Date.new/3:

{:ok, date} = Date.new(2026, 8, 21) date # ~D[2026-08-21]

Якщо передати некоректну дату, функція поверне помилку:

Date.new(2026, 2, 30) # {:error, :invalid_date}

Поточна дата

Поточну дату можна отримати за допомогою Date.utc_today/0:

date = Date.utc_today() IO.inspect(date) # ~D[2026-08-21]

Це аналогічно використанню LocalDate.now() у Java, хоча в Elixir явно вказано, що використовується UTC.

Час за допомогою Time

Тип Time використовується для представлення часу доби без дати та часового поясу:

time = ~T[14:30:00] time.hour # 14 
time.minute # 30 time.second # 0

Час можна створити через Time.new/3 або Time.new/4, якщо потрібно вказати мікросекунди:

{:ok, time} = Time.new(14, 30, 15) 
time # ~T[14:30:15]

Поточний час у UTC можна отримати за допомогою Time.utc_now/0:

time = Time.utc_now() 
IO.inspect(time) # ~T[08:42:17.123456]

NaiveDateTime

NaiveDateTime поєднує дату та час, але не містить інформації про часовий пояс. Назва Naive якраз підкреслює, що це "наївна" дата-часова величина.

datetime = ~N[2026-08-21 14:30:00] datetime.year # 2026 
datetime.month # 8 
datetime.day # 21 
datetime.hour # 14

Наприклад, значення ~N[2026-08-21 14:30:00] саме по собі не говорить, чи це 14:30 у Києві, Лондоні, Нью-Йорку чи іншому часовому поясі.

Приблизним аналогом у Java є LocalDateTime.

Коли використовувати NaiveDateTime

NaiveDateTime підходить тоді, коли часовий пояс не має значення. Наприклад, якщо потрібно зберегти локальний час, введений користувачем, але часовий пояс буде визначатися окремо.

meeting = ~N[2026-09-01 10:00:00]

Однак для подій, які відбуваються в конкретний момент часу у світі, наприклад для платежів, логів або моменту створення запису, зазвичай краще використовувати DateTime та UTC.

DateTime

DateTime використовується для представлення конкретної дати та часу з урахуванням часового поясу.

datetime = DateTime.utc_now() IO.inspect(datetime)

Результат може виглядати приблизно так:

~U[2026-08-21 08:45:12.123456Z]

Символ Z означає UTC.

Для створення UTC-дати можна використовувати sigil ~U:

datetime = ~U[2026-08-21 12:30:00Z]

У Java найближчим аналогом буде Instant або ZonedDateTime, залежно від того, чи потрібно зберігати лише момент часу, чи також часову зону.

Часові пояси

Одна з важливих відмінностей між NaiveDateTime і DateTime полягає саме в часовому поясі.

Наприклад, один і той самий момент часу можна представити в UTC та в часовому поясі Europe/Kyiv:

utc = ~U[2026-08-21 09:00:00Z] 
DateTime.shift_zone(utc, "Europe/Kyiv") # {:ok, ~U[2026-08-21 12:00:00+03:00]}

Для роботи з часовими поясами Elixir використовує календарну інфраструктуру та часові зони. У стандартному середовищі доступні UTC та деякі базові можливості, а для повноцінної роботи з базою часових зон часто використовується бібліотека tzdata.

Додавання та віднімання часу

Для роботи з датами можна використовувати функції модуля Date:

date = ~D[2026-08-21] 
Date.add(date, 10) # ~D[2026-08-31] 
Date.add(date, -10) # ~D[2026-08-11]

Таким способом можна додавати або віднімати кількість днів.

Різниця між датами

Функція Date.diff/2 дозволяє отримати кількість днів між двома датами:

date1 = ~D[2026-08-21] 
date2 = ~D[2026-09-01] 
Date.diff(date2, date1) # 11

Результат може бути і від'ємним:

Date.diff(date1, date2) # -11

Порівняння дат

Дати є звичайними значеннями Elixir, тому їх можна порівнювати за допомогою операторів:

date1 = ~D[2026-08-21] 
date2 = ~D[2026-09-01] 
date1 < date2 # true

Також можна використовувати функції Date.compare/2:

Date.compare(~D[2026-08-21], ~D[2026-09-01]) # :lt 
Date.compare(~D[2026-09-01], ~D[2026-08-21]) # :gt 
Date.compare(~D[2026-08-21], ~D[2026-08-21]) # :eq

Робота з компонентами дати та часу

Окремі компоненти можна отримати безпосередньо з відповідних структур:

date = ~D[2026-08-21] date.year # 2026 date.month # 8 date.day # 21

Для DateTime аналогічно:

datetime = ~U[2026-08-21 12:30:45Z] 
datetime.year # 2026 
datetime.hour # 12 
datetime.minute # 30 
datetime.second # 45

Форматування дат

Elixir має функції для перетворення дат у рядки та навпаки. Для складнішого форматування часто використовують бібліотеку Timex або власне форматування.

Простий варіант — використати Calendar.strftime/2:

date = ~D[2026-08-21] 
Calendar.strftime(date, "%Y-%m-%d") # "2026-08-21" 
Calendar.strftime(date, "%d.%m.%Y") # "21.08.2026"

Для DateTime це працює аналогічно:

datetime = ~U[2026-08-21 12:30:45Z] 
Calendar.strftime(datetime, "%Y-%m-%d %H:%M:%S") # "2026-08-21 12:30:45"

Основні символи форматування

Формат Значення Приклад
%Y Рік 2026
%m Місяць 08
%d День 21
%H Година 14
%M Хвилина 30
%S Секунда 45
%A Повна назва дня тижня Friday
%B Повна назва місяця August

Перетворення рядка в дату

Для перетворення рядка у структуру Date можна використовувати Date.from_iso8601/1:

Date.from_iso8601("2026-08-21") # {:ok, ~D[2026-08-21]}

Для ISO 8601 datetime можна використовувати DateTime.from_iso8601/1:

DateTime.from_iso8601("2026-08-21T12:30:00Z") # {:ok, ~U[2026-08-21 12:30:00Z], 0}

Це особливо важливо при роботі з REST API, JSON та базами даних, оскільки ISO 8601 є поширеним форматом передачі дат і часу.

Робота з часовими інтервалами

У Elixir існує структура Date.Range, яка дозволяє описувати діапазон дат:

range = Date.range(~D[2026-08-21], ~D[2026-08-25]) 
Enum.to_list(range) # [ # ~D[2026-08-21], # ~D[2026-08-22], # ~D[2026-08-23], # ~D[2026-08-24], # ~D[2026-08-25] # ]

Це добре поєднується з модулем Enum:

Date.range(~D[2026-08-21], ~D[2026-08-25]) |> 
Enum.each(fn date -> IO.inspect(date) end)

Мікросекунди

Типи часу та datetime підтримують мікросекундну точність:

time = ~T[14:30:15.123456] time.microsecond # {123456, 6}

Другий елемент кортежу показує точність значення.

Unix timestamp

Для представлення моменту часу у вигляді Unix timestamp можна використовувати DateTime.to_unix/1:

datetime = ~U[2026-08-21 12:00:00Z] 
DateTime.to_unix(datetime) # 1787313600

Зворотне перетворення виконується через DateTime.from_unix/1:

DateTime.from_unix(1787313600) # {:ok, ~U[2026-08-21 12:00:00Z]}

Який тип використовувати?

Тип Для чого використовувати Приблизний аналог Java
Date Календарна дата без часу LocalDate
Time Час доби без дати LocalTime
NaiveDateTime Дата + час без часового поясу LocalDateTime
DateTime Дата + час із часовою зоною ZonedDateTime
DateTime у UTC Конкретний момент часу Instant
Date.Range Діапазон дат Окремого прямого аналога немає

На що варто звернути увагу Java-розробнику

Для Java-розробника концепція роботи з датами в Elixir багато в чому знайома завдяки сучасному API java.time. Наприклад, Date приблизно відповідає LocalDate, а NaiveDateTime — LocalDateTime.

Однак важлива відмінність полягає у функціональній природі Elixir. Значення дат і часу є іммутабельними. Функція, яка змінює дату або час, не модифікує існуюче значення, а повертає нове:

date = ~D[2026-08-21] new_date = Date.add(date, 10) 
IO.inspect(date) # ~D[2026-08-21] 
IO.inspect(new_date) # ~D[2026-08-31]

Це відповідає загальній моделі Elixir, де дані не змінюються після створення.

Коментарі

Популярні публікації

Встановлення Visual Studio Code на Ubuntu

Visual Studio Code (VS Code) — це потужний, легкий та кросплатформний редактор коду, який став стандартом для розробників завдяки універсальності та швидкості роботи. Він підтримує Windows, Linux і macOS, запускається швидше за повноцінні IDE, але водночас може перетворюватися на повнофункціональне середовище розробки завдяки тисячам розширень. VS Code має продуману архітектуру, інтуїтивний інтерфейс, вбудований термінал та інтелектуальну систему автодоповнення на базі Language Server Protocol, що забезпечує високоякісну підтримку синтаксису для багатьох мов програмування. Серед ключових можливостей — розумне автодоповнення коду (IntelliSense), навігація між класами, символами та файлами, рефакторинг, форматування коду, інтеграція з Git, підтримка віддаленої розробки через SSH або контейнерні середовища (Dev Containers). Завдяки відлагоджувачу (debugger), який налаштовується під будь-яку мову, розробник може запускати код у контрольованому середовищі, ставити брейкпоїнти, переглядат...

Керуючі конструкції в Elixir

Elixir пропонує різноманітні керуючі конструкції для управління потоком виконання програми. На відміну від імперативних мов, всі конструкції в Elixir повертають значення, що робить код більш виразним. if та else Конструкція if перевіряє умову і виконує код відповідно до результату: # Базовий синтаксис if true do "Це буде виконано" else "Це не буде виконано" end # Однорядковий варіант if connected?, do: "Підключено", else: "Відключено" # Присвоєння результату message = if age >= 18 do "Ви повнолітній" else "Ви неповнолітній" end # Без else (повертає nil) if user_logged_in? do show_dashboard() end Примітка: В Elixir тільки false і nil вважаються хибними. Всі інші значення (включаючи 0, "", []) вважаються істинними. unless Конструкція unless — це протилежність if, виконується коли умова хибна: # ...

Шпаргалка по базових командах PostgreSQL

1. Підключення до PostgreSQL через командний рядок: psql -h <host> -p <port> -U <username> -d <database> 2. Підключення до бази без параметрів (якщо користувач і база мають однакове ім’я): psql 3. Показати список усіх баз даних: \l 4. Підключитися до іншої бази даних: \c <database_name> 5. Показати список таблиць у поточній базі: \dt 6. Показати всі об'єкти (таблиці, індекси, секвенції): \d 7. Показати таблиці з усіх схем: \dt *.* 8. Переглянути структуру конкретної таблиці: \d <table_name> 9. Виконати SQL-запит (приклад): SELECT * FROM users; 10. Вийти з psql: \q 11. Створити нову базу даних: CREATE DATABASE mydb; 12. Створити нову таблицю: CREATE TABLE users ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE ); 13. Додати новий запис: INSERT INTO users (name, email) VALUES ('Іван', 'ivan@example.com'); 14. Оновити дані в таблиці: UPDATE users SET name = 'Петро' WH...

Angular CLI

CLI (command-line interface) – інтерфейс командного рядка. Перед початком роботи має бути встановлений Node.js Встановлення: npm install -g @angular/cli Отримання допомоги: ng help Буде приблизно такий результат: add Adds support for an external library to your project. analytics Configures the gathering of Angular CLI usage metrics. See https://angular.io/cli/usage-analytics-gathering. build (b) Compiles an Angular app into an output directory named dist/ at the given output path. Must be executed from within a workspace directory. deploy Invokes the deploy builder for a specified project or for the default project in the workspace. config Retrieves or sets Angular configuration values in the angular.json file for the workspace. doc (d) Opens the official Angular documentation (angular.io) in a browser, and searches for a given keyword. e2e (e) Builds and serves an Angular app, then runs end-to-end tests. extract-i18n (i18n-extract, xi18n) Extracts i18n mes...

Дамп бази даних Postgresql локально

Що потрібно встановити локально (Ubuntu) Встанови клієнтські утиліти PostgreSQL: pg_dump , psql , pg_restore . sudo apt update sudo apt install postgresql-client Кроки міграції Ідея: не зберігати дамп на серверах. Зробити дамп з віддаленого сервера на свій локальний ПК, потім передати його на новий сервер і там відновити. 1) Створення дампу з віддаленого сервера локально pg_dump -h OLD_SERVER_IP -U OLD_USER -Fc -d OLD_DB -f dump_file.dump Пояснення ключів: -h (хост), -U (користувач), -Fc (custom format), -d (БД), -f (вихідний файл локально). 1.1) Варіант з розбиттям на частини (якщо треба) pg_dump -h OLD_SERVER_IP -U OLD_USER -Fc -d OLD_DB | split -b 10G - dump_file.dump.part_ Це створить локально файли типу dump_file.dump.part_aa , dump_file.dump.part_ab тощо. 2) Передача дампу на новий сервер Один файл: scp dump_file.dump NEW_USER@NEW_SERVER_IP:/tmp/ Або частинами: scp dump_file.dump.part_* NEW_USER@NEW_SERVER_IP:/tmp/ 3) Збирання файл...