«Дати й час ми вчимо малих дітей. Що в цьому складного?»
Багато програмістів припускалися цієї помилки, і подальший досвід зазвичай погано позначається на їхньому здоровʼї та щасті.
Кожен, хто займається нетривіальним програмуванням із датами й часом, має принаймні бути готовим розуміти й помʼякшувати потенційні проблеми.
У цьому документі ми спробуємо дати огляд того, як Julia працює з датами й часом, але для подробиць доведеться звернутися до посібника. Є також Вікіпідручник, чиї пояснення деяким читачам можуть здатися зрозумілішими, і в ньому є корисна діаграма ієрархії типів.
Dates
Більшість базової функціональності міститься в Dates, модулі, який входить до типової інсталяції, але не є частиною стандартної бібліотеки.
Щоб скористатися модулем, є два варіанти:
import Dates, а потім додаватимемо Dates. перед усіма викликами функцій.using Dates, що вносить увесь модуль у поточний простір імен (крім кількох проблемних назв).# option 1
julia> import Dates
julia> Dates.now()
2025-06-21T16:02:39.080
julia> now() # wrong: need to include `Dates.` after an import
ERROR: UndefVarError: `now` not defined in `Main`
# option 2
julia> using Dates
julia> now() # functions are now in the namespace
2025-06-21T16:03:04.161
Модуль Dates великий і складний, але він надає чотири основні типи функціональності:
Dates.Date, який містить день, місяць і рік, але без часу доби.Dates.Time, який містить час доби, але без дати.Dates.DateTime, який поєднує дату й час.Dates.Period, який опрацьовує інтервали часу й дат.Зауважмо, що DateTime зазвичай не містить інформації про часовий пояс (Python назвав би це «наївним» datetime).
Один виняток - now(), який бере місцевий час із системного годинника й за потреби може перетворити його на UTC.
Мабуть, найчастіші потреби такі:
Dates.Dates потрібний числовий формат або рядок тексту (англ. string).Date, Time або DateTime.today()) та/або час (за допомогою now()).Щоб зменшити візуальне відволікання, більшість прикладів коду в решті цього документа припускає using Dates і не включає назву модуля Dates. у виклики функцій.
Існує багато способів записувати дати й час, і вони зазвичай залежать від культури. Дати, записані самими числами, як-от «7/6/23», неоднозначні, заплутані й призводили до багатьох дорогих помилок у міжнародних організаціях (автор каже це з гіркого особистого досвіду).
Міжнародний стандарт визначено в ISO 8601, і він має дві головні переваги:
У попередньому прикладі ми бачили, що Date.now() повернув 2025-06-21T16:03:04.161.
Він складається з різних частин:
YYYY-MM-DD для частини з датою.hh:mm:ss для частини з часом.Інші формати рядків тексту ми обговоримо в пізнішому розділі.
Dates.Date - відносно простий тип лише для дати, який нічого не знає про час чи часові пояси.
# constructor with year, month, day arguments
julia> date1 = Date(2025, 06, 23)
2025-06-23
# constructor with ISO 8601 string
julia> date2 = Date("2025-06-23")
2025-06-23
julia> date1 == date2
true
julia> typeof(date1)
Date
Для окремих частин дати є функції доступу, і вони йдуть парами, які розрізняються регістром.
# lowercase returns an integer
julia> month(date1)
6
julia> typeof(month(date1))
Int64
# Propercase returns a Period type
julia> Month(date1)
6 months
julia> typeof(Month(date1))
Month
Є чимало функцій, які дещо знають про календар. Наступний приклад показує лише кілька з них.
julia> date1
2025-06-23
julia> dayofweek(date1) # 1 = Monday, 7 = Sunday
1
julia> dayname(date1)
"Monday"
julia> daysinmonth(date1)
30
julia> isleapyear(date1)
false
julia> lastdayofmonth(date1)
2025-06-30
Dates.Time - базовий тип лише для часу.
Він нічого не знає про дати: час автоматично переходить до Time(0, 0, 0) опівночі.
Повний формат конструктора - Time(hour, min, sec, millisec, microsec) або його еквівалент за ISO 8601.
Усі параметри необовʼязкові й типово дорівнюють 0.
julia> Time(14, 57, 25, 142)
14:57:25.142
julia> Time("14:57:25.142")
14:57:25.142
julia> Time(14, 57, 25, 142, 32)
14:57:25.142032
Як і з Date, окремі частини доступні через функції доступу:
julia> minute(t) # => integer
57
julia> Minute(t) # => Period
57 minutes
Dates.DateTime поєднує більшість можливостей типів Date і Time.
julia> dt1 = DateTime(2025, 6, 23, 14, 57, 25, 142)
2025-06-23T14:57:25.142
# date1 and t were defined in previous examples
julia> dt2 = DateTime(date1, t)
2025-06-23T14:57:25.142
Параметри року, місяця й дня типово дорівнюють 1, а параметри часу - 0.
Не заплутатися в усіх цих параметрах - непросте завдання, тож для вхідних даних формат ISO може виявитися кращим.
Або ж DateTime можна побудувати з Date і Time, як у наведеному вище прикладі.
Кожен із компонентів дати й часу має власний тип Period, від Year аж до Nanosecond, що представляє інтервал часу.
Вони особливо корисні для арифметики.
julia> dt1
2025-06-23T14:57:25.142
julia> Year(21)
21 years
julia> Second(61)
61 seconds
julia> dt1 + Year(21) - Second(61)
2046-06-23T14:56:24.142
julia> Date(2025, 07, 03) - Date(2025, 04, 25)
69 days
Працюючи з типами Period, Julia намагається розумно поводитися з календарними нерівностями, як-от довжина місяця, округлюючи за потреби.
# February has fewer days than January
julia> Date(2025, 1, 31) + Month(1)
2025-02-28
Раніше ми згадували стандарт ISO 8601 - типове подання дати й часу в Julia під час форматування чи розбору рядків тексту.
Очевидно, часто використовують багато інших форматів, нерідко з огляду на культурні особливості.
Щоб їх опрацьовувати, у Julia є тип DateFormat, який можна побудувати з рядка формату довільної складності.
# dateformat"" string syntax
julia> dtfmt = dateformat"d/m/y"
dateformat"d/m/y"
julia> typeof(dtfmt)
DateFormat{Symbol("d/m/y"), Tuple{Dates.DatePart{'d'}, Dates.Delim{Char, 1}, Dates.DatePart{'m'}, Dates.Delim{Char, 1}, Dates.DatePart{'y'}}}
# DateFormat constructor
julia> DateFormat("d/m/y")
dateformat"d/m/y"
Наведений вище приклад дуже простий: лише дата у форматі день/місяць/рік, поширеному в Європі. Показано два варіанти синтаксису, але результат однаковий.
Тоді DateFormat можна використати для розбору будь-якого відповідного рядка тексту:
julia> DateTime("14/7/2023", dtfmt)
2023-07-14T00:00:00
Створення DateFormat повʼязане зі значними накладними витратами, тож виконати цей крок лише раз (як тут із dtfmt) корисно для швидкодії, коли ми перебираємо багато рядків тексту з датами й часом.
Формати можуть бути значно складнішими за це, тож для подробиць звернімося до посібника.
Той самий DateFormat можна також використати, щоб вивести дату й час у будь-якому бажаному форматі рядка тексту, за допомогою функції Dates.format().
На жаль, схоже, є конфлікт просторів імен із format (принаймні станом на Julia 1.11.5), тож краще додавати префікс Dates. навіть після using Dates.
julia> dt1
2025-06-23T14:57:25.142
julia> Dates.format(dt1, dateformat"e, u d")
"Mon, Jun 23"
Як задокументовано, "e, u d" дає скорочене текстове подання для дня тижня й місяця.
Текстове подання типово англійською. Можна додати інші мови, хоча нині підтримка цього не найкраща.
У цій вправі ми працюватимемо над планувальником зустрічей для салону краси в Нью-Йорку, який відкрився 15 вересня 2012 року.
На нас чекає пʼять завдань, і всі вони стосуються дат зустрічей. Час подано у 24-годинному форматі (без позначок AM/PM).
Реалізуйте функцію schedule_appointment(), яка перетворює текстове подання дати зустрічі у відповідний формат DateTime.
Зауважте, що вхідні дані подано в американському порядку місяць/день/рік.
julia> schedule_appointment("07/25/2023 13:45:00")
2023-07-25T13:45:00
Реалізуйте функцію has_passed(), яка приймає дату зустрічі й перевіряє, чи зустріч була десь у минулому:
julia> has_passed(DateTime(1999, 12, 31, 9, 0, 0))
true
Реалізуйте функцію is_afternoon_appointment(), яка приймає дату зустрічі й перевіряє, чи призначено зустріч на післяобідній час (>= 12:00 та < 18:00):
julia> is_afternoon_appointment(DateTime(2023, 3, 29, 15, 0, 0))
true
Реалізуйте функцію description(), яка приймає дату зустрічі й повертає опис цієї дати й часу:
julia> describe(DateTime(2023, 3, 29, 15, 0, 0))
"You have an appointment on Wednesday, March 29, 2023 at 15:00"
Реалізуйте функцію anniversary_date(), яка повертає дату річниці цього року, а саме 15 вересня:
julia> anniversary_date() # run during 2025
2025-09-15
Зареєструйтеся на Exercism, щоб вивчати й опановувати Julia, а також 35 концепцій128 вправ та справжнє наставництво від людей, і все це безкоштовно.