75 lines
2.6 KiB
Lua
75 lines
2.6 KiB
Lua
|
|
-- "Сколько дней до нового года" / "сколько до 15 марта"
|
|||
|
|
local phrase = (jarvis.context.phrase or ""):lower()
|
|||
|
|
local t = jarvis.context.time
|
|||
|
|
local current_year = t.year
|
|||
|
|
|
|||
|
|
local MONTHS = {
|
|||
|
|
["январ"]=1, ["феврал"]=2, ["март"]=3, ["апрел"]=4, ["май"]=5, ["мая"]=5, ["июн"]=6,
|
|||
|
|
["июл"]=7, ["август"]=8, ["сентябр"]=9, ["октябр"]=10, ["ноябр"]=11, ["декабр"]=12,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
-- Special phrases
|
|||
|
|
local target_y, target_m, target_d
|
|||
|
|
|
|||
|
|
if phrase:find("нов") and phrase:find("год") then
|
|||
|
|
target_y, target_m, target_d = current_year + 1, 1, 1
|
|||
|
|
if t.month == 1 and t.day == 1 then target_y = current_year end
|
|||
|
|
elseif phrase:find("рожд") then
|
|||
|
|
target_y, target_m, target_d = current_year, 1, 7 -- ru orthodox
|
|||
|
|
elseif phrase:find("8 март") or phrase:find("восьмого март") then
|
|||
|
|
target_y, target_m, target_d = current_year, 3, 8
|
|||
|
|
elseif phrase:find("9 ма") or phrase:find("девятое ма") then
|
|||
|
|
target_y, target_m, target_d = current_year, 5, 9
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- Generic "до N <месяц>"
|
|||
|
|
if not target_y then
|
|||
|
|
local d = tonumber(phrase:match("до%s+(%d+)"))
|
|||
|
|
if d then
|
|||
|
|
for stem, month in pairs(MONTHS) do
|
|||
|
|
if phrase:find(stem) then
|
|||
|
|
target_d, target_m, target_y = d, month, current_year
|
|||
|
|
break
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
if not target_y then
|
|||
|
|
return jarvis.cmd.error("Не понял дату.")
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- If target this year already passed, jump to next year
|
|||
|
|
local function days_since_epoch(y, m, d)
|
|||
|
|
-- approximate: works for diffs within ~100 years
|
|||
|
|
local total = y * 365 + math.floor(y / 4) - math.floor(y / 100) + math.floor(y / 400)
|
|||
|
|
local cum = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }
|
|||
|
|
total = total + cum[m] + (d - 1)
|
|||
|
|
-- leap-day adjustment
|
|||
|
|
local leap = (y % 4 == 0 and y % 100 ~= 0) or (y % 400 == 0)
|
|||
|
|
if leap and m > 2 then total = total + 1 end
|
|||
|
|
return total
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local now = days_since_epoch(t.year, t.month, t.day)
|
|||
|
|
local target = days_since_epoch(target_y, target_m, target_d)
|
|||
|
|
|
|||
|
|
if target < now then
|
|||
|
|
target_y = target_y + 1
|
|||
|
|
target = days_since_epoch(target_y, target_m, target_d)
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
local diff = target - now
|
|||
|
|
if diff == 0 then
|
|||
|
|
return jarvis.cmd.ok("Сегодня.")
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
-- Russian grammar: 1 день, 2-4 дня, 5+ дней
|
|||
|
|
local last = diff % 10
|
|||
|
|
local unit = "дней"
|
|||
|
|
if last == 1 and diff % 100 ~= 11 then unit = "день"
|
|||
|
|
elseif last >= 2 and last <= 4 and (diff % 100 < 10 or diff % 100 >= 20) then unit = "дня"
|
|||
|
|
end
|
|||
|
|
|
|||
|
|
return jarvis.cmd.ok(string.format("%d %s.", diff, unit))
|