Время и длительности
Время и длительности
Заголовок раздела «Время и длительности»Работа со значениями времени, длительностями, часовыми поясами и планированием. Создание таймеров, паузы на заданные периоды, парсинг и форматирование временных меток.
В workflows time.now() возвращает записанную ссылку времени для детерминированного воспроизведения.
Загрузка
Заголовок раздела «Загрузка»local time = require("time")Текущее время
Заголовок раздела «Текущее время»Возвращает текущее время. В workflows возвращает записанное время из ссылки времени workflow для детерминированного воспроизведения.
local t = time.now()print(t:format_rfc3339()) -- "2024-12-29T15:04:05Z"
-- Измерение прошедшего времениlocal start = time.now()do_work()local elapsed = time.now():sub(start)print("Заняло " .. elapsed:milliseconds() .. "ms")Возвращает: Time
Создание значений времени
Заголовок раздела «Создание значений времени»Из компонентов
Заголовок раздела «Из компонентов»-- Создать конкретную дату/время в UTClocal t = time.date(2024, time.DECEMBER, 25, 10, 30, 0, 0, time.utc)print(t:format_rfc3339()) -- "2024-12-25T10:30:00Z"
-- Создать в конкретном часовом поясеlocal ny, _ = time.load_location("America/New_York")local meeting = time.date(2024, time.JANUARY, 15, 14, 0, 0, 0, ny)
-- По умолчанию локальный часовой пояс, если не указанlocal t = time.date(2024, 1, 15, 12, 0, 0, 0)| Параметр | Тип | Описание |
|---|---|---|
year | number | Год |
month | number | Месяц (1-12 или time.JANUARY и т.д.) |
day | number | День месяца |
hour | number | Час (0-23) |
minute | number | Минута (0-59) |
second | number | Секунда (0-59) |
nanosecond | number | Наносекунда (0-999999999) |
location | Location | Часовой пояс (опционально, по умолчанию локальный) |
Возвращает: Time
Из Unix timestamp
Заголовок раздела «Из Unix timestamp»-- Из секунд с эпохиlocal t = time.unix(1703862245, 0)print(t:utc():format_rfc3339()) -- "2023-12-29T15:04:05Z"
-- С наносекундамиlocal t = time.unix(1703862245, 500000000) -- +500ms
-- Преобразование JavaScript timestamp (миллисекунды)local js_timestamp = 1703862245000local t = time.unix(js_timestamp // 1000, (js_timestamp % 1000) * 1000000)| Параметр | Тип | Описание |
|---|---|---|
sec | number | Unix секунды |
nsec | number | Смещение в наносекундах |
Возвращает: Time
Из строки
Заголовок раздела «Из строки»Парсинг строк времени с использованием формата Go reference time: Mon Jan 2 15:04:05 MST 2006.
-- Парсинг RFC3339local t, err = time.parse(time.RFC3339, "2024-12-29T15:04:05Z")if err then return nil, errend
-- Парсинг пользовательского форматаlocal t, err = time.parse("2006-01-02", "2024-12-29")local t, err = time.parse("15:04:05", "14:30:00")local t, err = time.parse("2006-01-02 15:04:05 MST", "2024-12-29 14:30:00 EST")
-- Парсинг в конкретном часовом поясеlocal ny, _ = time.load_location("America/New_York")local t, err = time.parse("2006-01-02 15:04", "2024-12-29 14:30", ny)| Параметр | Тип | Описание |
|---|---|---|
layout | string | Шаблон формата времени Go |
value | string | Строка для парсинга |
location | Location | Часовой пояс по умолчанию (опционально) |
Возвращает: Time, error
Методы Time
Заголовок раздела «Методы Time»Арифметика
Заголовок раздела «Арифметика»local t = time.now()
-- Добавить длительность (принимает число, строку или Duration)local tomorrow = t:add("24h")local later = t:add(5 * time.MINUTE)local d, _ = time.parse_duration("1h30m")local future = t:add(d)
-- Вычесть время для получения длительностиlocal diff = tomorrow:sub(t) -- возвращает Durationprint(diff:hours()) -- 24
-- Добавить календарные единицы (правильно обрабатывает границы месяцев)local next_month = t:add_date(0, 1, 0) -- добавить 1 месяцlocal next_year = t:add_date(1, 0, 0) -- добавить 1 годlocal last_week = t:add_date(0, 0, -7) -- вычесть 7 дней| Метод | Параметры | Возвращает | Описание |
|---|---|---|---|
add(duration) | number/string/Duration | Time | Добавить длительность |
sub(time) | Time | Duration | Разница между временами |
add_date(years, months, days) | numbers | Time | Добавить календарные единицы |
Сравнение
Заголовок раздела «Сравнение»local t1 = time.date(2024, 1, 1, 0, 0, 0, 0, time.utc)local t2 = time.date(2024, 1, 2, 0, 0, 0, 0, time.utc)
t1:before(t2) -- truet2:after(t1) -- truet1:equal(t1) -- true| Метод | Параметры | Возвращает | Описание |
|---|---|---|---|
before(time) | Time | boolean | Это время раньше другого? |
after(time) | Time | boolean | Это время позже другого? |
equal(time) | Time | boolean | Времена равны? |
Форматирование
Заголовок раздела «Форматирование»local t = time.now()
t:format_rfc3339() -- "2024-12-29T15:04:05Z"t:format(time.DATE_ONLY) -- "2024-12-29"t:format(time.TIME_ONLY) -- "15:04:05"t:format("Mon Jan 2, 2006") -- "Sun Dec 29, 2024"| Метод | Параметры | Возвращает | Описание |
|---|---|---|---|
format(layout) | string | string | Форматировать по шаблону Go |
format_rfc3339() | - | string | Форматировать как RFC3339 |
Unix Timestamps
Заголовок раздела «Unix Timestamps»local t = time.now()
t:unix() -- секунды с эпохиt:unix_nano() -- наносекунды с эпохиКомпоненты
Заголовок раздела «Компоненты»local t = time.now()
-- Получить части датыlocal year, month, day = t:date()
-- Получить части времениlocal hour, min, sec = t:clock()
-- Отдельные аксессорыt:year() -- например, 2024t:month() -- 1-12t:day() -- 1-31t:hour() -- 0-23t:minute() -- 0-59t:second() -- 0-59t:nanosecond() -- 0-999999999t:weekday() -- 0=Воскресенье .. 6=Субботаt:year_day() -- 1-366t:is_zero() -- true если нулевое значениеПреобразование часовых поясов
Заголовок раздела «Преобразование часовых поясов»local t = time.now()
t:utc() -- преобразовать в UTCt:in_local() -- преобразовать в локальный часовой поясt:in_location(ny) -- преобразовать в конкретный часовой поясt:location() -- получить текущий Locationt:location():string() -- получить имя часового пояса| Метод | Параметры | Возвращает | Описание |
|---|---|---|---|
utc() | - | Time | Преобразовать в UTC |
in_local() | - | Time | Преобразовать в локальный пояс |
in_location(loc) | Location | Time | Преобразовать в часовой пояс |
location() | - | Location | Получить текущий часовой пояс |
Округление
Заголовок раздела «Округление»Округление или усечение до границ длительности. Требуется userdata Duration (не число или строка).
local t = time.now()local hour_duration, _ = time.parse_duration("1h")local minute_duration, _ = time.parse_duration("15m")
t:round(hour_duration) -- округлить до ближайшего часаt:truncate(minute_duration) -- усечь до 15-минутной границы| Метод | Параметры | Возвращает | Описание |
|---|---|---|---|
round(duration) | Duration | Time | Округлить до ближайшего кратного |
truncate(duration) | Duration | Time | Усечь до кратного |
Длительности
Заголовок раздела «Длительности»Создание длительностей
Заголовок раздела «Создание длительностей»-- Парсинг из строкиlocal d, err = time.parse_duration("1h30m45s")local d, err = time.parse_duration("500ms")local d, err = time.parse_duration("2h30m45s500ms")
-- Из числа (наносекунды)local d, err = time.parse_duration(time.SECOND)local d, err = time.parse_duration(5 * time.MINUTE)
-- Допустимые единицы: ns, us, ms, s, m, h| Параметр | Тип | Описание |
|---|---|---|
value | number/string/Duration | Длительность для парсинга |
Возвращает: Duration, error
Методы Duration
Заголовок раздела «Методы Duration»local d, _ = time.parse_duration("1h30m45s500ms")
d:hours() -- 1.5125...d:minutes() -- 90.75...d:seconds() -- 5445.5d:milliseconds() -- 5445500d:microseconds() -- 5445500000d:nanoseconds() -- 5445500000000Часовые пояса
Заголовок раздела «Часовые пояса»Загрузка по имени
Заголовок раздела «Загрузка по имени»Загрузка часового пояса по IANA-имени (например, “America/New_York”, “Europe/London”, “Asia/Tokyo”).
local ny, err = time.load_location("America/New_York")if err then return nil, errend
local tokyo, _ = time.load_location("Asia/Tokyo")local london, _ = time.load_location("Europe/London")
-- Преобразование между часовыми поясамиlocal t = time.now():utc()print("UTC:", t:format(time.TIME_ONLY))print("New York:", t:in_location(ny):format(time.TIME_ONLY))print("Tokyo:", t:in_location(tokyo):format(time.TIME_ONLY))| Параметр | Тип | Описание |
|---|---|---|
name | string | IANA-имя часового пояса |
Возвращает: Location, error
Фиксированное смещение
Заголовок раздела «Фиксированное смещение»Создание часового пояса с фиксированным смещением UTC.
-- UTC+5:30 (India Standard Time)local ist = time.fixed_zone("IST", 5*3600 + 30*60)
-- UTC-8 (Pacific Standard Time)local pst = time.fixed_zone("PST", -8*3600)
local t = time.date(2024, 1, 15, 12, 0, 0, 0, ist)| Параметр | Тип | Описание |
|---|---|---|
name | string | Имя зоны |
offset | number | Смещение UTC в секундах |
Возвращает: Location
Встроенные Location
Заголовок раздела «Встроенные Location»time.utc -- Часовой пояс UTCtime.localtz -- Локальный системный часовой поясПланирование
Заголовок раздела «Планирование»Пауза выполнения на указанную длительность. В workflows записывается и воспроизводится корректно.
time.sleep("5s")time.sleep(500 * time.MILLISECOND)
-- Паттерн backofffor attempt = 1, 3 do local ok = try_operation() if ok then break end time.sleep(tostring(attempt) .. "s")end| Параметр | Тип | Описание |
|---|---|---|
duration | number/string/Duration | Время паузы |
Возвращает канал, получающий значение один раз после истечения длительности. Работает с channel.select.
-- Простой таймаутlocal timeout = time.after("5s")timeout:receive() -- блокируется на 5 секунд
-- Таймаут с selectlocal response_ch = make_request()local timeout_ch = time.after("30s")
local result = channel.select{ response_ch:case_receive(), timeout_ch:case_receive()}
if result.channel == timeout_ch then return nil, errors.new({message = "Request timed out", kind = errors.TIMEOUT})end| Параметр | Тип | Описание |
|---|---|---|
duration | number/string/Duration | Время ожидания |
Возвращает: Channel
Одноразовый таймер, срабатывающий после длительности. Можно остановить или сбросить.
local timer = time.timer("5s")
-- Ждать таймерtimer:response():receive()send_reminder()
-- Сброс при активностиlocal idle_timer = time.timer("5m")while true do local r = channel.select{ user_activity:case_receive(), idle_timer:response():case_receive() } if r.channel == idle_timer:response() then logout_user() break end idle_timer:reset("5m")end
-- Остановить таймерtimer:stop()| Параметр | Тип | Описание |
|---|---|---|
duration | number/string/Duration | Время до срабатывания |
Возвращает: Timer, error
| Метод Timer | Параметры | Возвращает | Описание |
|---|---|---|---|
response() | - | Channel | Получить канал таймера |
channel() | - | Channel | Псевдоним для response() |
stop() | - | boolean | Отменить таймер |
reset(duration) | number/string/Duration | boolean | Сбросить с новой длительностью |
Повторяющийся таймер, срабатывающий через регулярные интервалы.
-- Периодическая задачаlocal ticker = time.ticker("30s")local ch = ticker:response()
while true do local tick_time = ch:receive() check_health()end
-- Ограничение частотыlocal ticker = time.ticker("100ms")for _, item in ipairs(items) do ticker:response():receive() process(item)endticker:stop()| Параметр | Тип | Описание |
|---|---|---|
duration | number/string/Duration | Интервал между тиками |
Возвращает: Ticker, error
| Метод Ticker | Параметры | Возвращает | Описание |
|---|---|---|---|
response() | - | Channel | Получить канал тикера |
channel() | - | Channel | Псевдоним для response() |
stop() | - | boolean | Остановить тикер |
Константы
Заголовок раздела «Константы»Единицы длительности
Заголовок раздела «Единицы длительности»Константы длительности в наносекундах. Используйте в арифметике.
time.NANOSECOND -- 1time.MICROSECOND -- 1,000time.MILLISECOND -- 1,000,000time.SECOND -- 1,000,000,000time.MINUTE -- 60 * SECONDtime.HOUR -- 60 * MINUTE
-- Пример использованияtime.sleep(5 * time.SECOND)local timeout = time.after(30 * time.SECOND)Шаблоны форматов
Заголовок раздела «Шаблоны форматов»time.RFC3339 -- "2006-01-02T15:04:05Z07:00"time.RFC3339NANO -- "2006-01-02T15:04:05.999999999Z07:00"time.RFC822 -- "02 Jan 06 15:04 MST"time.RFC822Z -- "02 Jan 06 15:04 -0700"time.RFC850 -- "Monday, 02-Jan-06 15:04:05 MST"time.RFC1123 -- "Mon, 02 Jan 2006 15:04:05 MST"time.RFC1123Z -- "Mon, 02 Jan 2006 15:04:05 -0700"time.DATE_TIME -- "2006-01-02 15:04:05"time.DATE_ONLY -- "2006-01-02"time.TIME_ONLY -- "15:04:05"time.KITCHEN -- "3:04PM"time.STAMP -- "Jan _2 15:04:05"time.STAMP_MILLI -- "Jan _2 15:04:05.000"time.STAMP_MICRO -- "Jan _2 15:04:05.000000"time.STAMP_NANO -- "Jan _2 15:04:05.000000000"time.JANUARY -- 1time.FEBRUARY -- 2time.MARCH -- 3time.APRIL -- 4time.MAY -- 5time.JUNE -- 6time.JULY -- 7time.AUGUST -- 8time.SEPTEMBER -- 9time.OCTOBER -- 10time.NOVEMBER -- 11time.DECEMBER -- 12Дни недели
Заголовок раздела «Дни недели»time.SUNDAY -- 0time.MONDAY -- 1time.TUESDAY -- 2time.WEDNESDAY -- 3time.THURSDAY -- 4time.FRIDAY -- 5time.SATURDAY -- 6| Условие | Kind | Повторяемо |
|---|---|---|
| Неверный формат длительности | errors.INVALID | нет |
| Парсинг не удался | errors.INTERNAL | нет |
| Пустое имя location | errors.INVALID | нет |
| Location не найден | errors.INTERNAL | нет |
| Duration <= 0 (timer/ticker) | errors.INVALID | нет |
local t, err = time.parse(time.RFC3339, "invalid")if err then if errors.is(err, errors.INVALID) then print("Неверный формат:", err:message()) end return nil, errend
local loc, err = time.load_location("Unknown/Zone")if err then if errors.is(err, errors.INTERNAL) then print("Location не найден:", err:message()) end return nil, errendСм. Обработка ошибок для работы с ошибками.