پودمان:Iranian calendar/library
-- This module is under development.
-- A library of Iranian calendar functions -- Written and bringing more features by Alireza Eskandarpour Shoferi (@AEsShoferi) in Lua -- Based on JalaliJSCalendar (by Ali Farhadi) -- -- Distributed under the terms of the CC BY-SA 4.0
local p = {}
local daysMonth = { gregorian = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, jalali = {31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29} }
local gregorianWords = { abbrDays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}, abbrMonths = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}, days = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}, months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}, abbrClock = {"AM", "PM"} }
local IranianWords = { abbrDays = {"یک", "دو", "سه", "چها", "پنج", "جمع", "شنب"}, abbrMonths = {"فرو", "ارد", "خرد", "تیر", "مرد", "شهر", "مهر", "آبا", "آذر", "دی", "بهم", "اسف"}, days = {"یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه"}, months = {"فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند"}, abbrClock = {"ق.ظ", "ب.ظ"} }
function p.jalaliToGregorian(frame) local jy = frame.args[1] -979 local jm = frame.args[2] -1 local jd = frame.args[3] -1
local j_day_no = 365 * jy + math.floor(jy / 33) * 8 + math.floor((jy % 33 + 3) / 4) local i = 1 while i <= jm do j_day_no = j_day_no + daysMonth.jalali[i] i = i + 1 end
j_day_no = j_day_no + jd
local g_day_no = j_day_no + 79
-- 146097 = 365*400 + 400/4 - 400/100 + 400/400 local gy = 1600 + 400 * math.floor(g_day_no / 146097) g_day_no = g_day_no % 146097
local leap = true -- 36525 = 365*100 + 100/4 if (g_day_no >= 36525) then g_day_no = g_day_no - 1 -- 36524 = 365*100 + 100/4 - 100/100 gy = gy + 100 * math.floor(g_day_no / 36524) g_day_no = g_day_no % 36524
if (g_day_no >= 365) then g_day_no = g_day_no + 1 else leap = false end end
-- 1461 = 365*4 + 4/4 gy = gy + 4 * math.floor(g_day_no / 1461) g_day_no = g_day_no % 1461
if (g_day_no >= 366) then leap = false
g_day_no = g_day_no - 1 gy = gy + math.floor(g_day_no / 365) g_day_no = g_day_no % 365 end
i = 1 while g_day_no > daysMonth.gregorian[i] +((i == 1 and leap) and 1 or 0) do g_day_no = g_day_no - daysMonth.gregorian[i] +((i == 1 and leap) and 1 or 0) i = i + 1 end local gm = i local gd = g_day_no + 1
return {gy, gm, gd} end
function p.checkDate(frame) return not(tonumber(frame.args[1]) < 0 or tonumber(frame.args[1]) > 32767 or tonumber(frame.args[2]) < 1 or tonumber(frame.args[2]) > 12 or tonumber(frame.args[3]) < 1 or tonumber(frame.args[3]) > (daysMonth.jalali[frame.args[2] -1] +((tonumber(frame.args[2]) == 12 and not((tonumber(frame.args[1]) -979) % 33 % 4)) and 1 or 0))) end
function p.gregorianToJalali(frame) local gy = frame.args[1] -1600 local gm = frame.args[2] -1 local gd = frame.args[3] -1
local g_day_no = 365 * gy + math.floor((gy + 3) / 4) - math.floor((gy + 99) / 100) + math.floor((gy + 399) / 400)
local i = 1 while i <= gm do g_day_no = g_day_no + daysMonth.gregorian[i] i = i + 1 end if (gm > 1 and((gy % 4 == 0 and gy % 100 ~= 0) or(gy % 400 == 0))) then -- leap and after Feb g_day_no = g_day_no + 1 end g_day_no = g_day_no + gd
local j_day_no = g_day_no - 79
local j_np = math.floor(j_day_no / 12053) j_day_no = j_day_no % 12053
local jy = 979 + 33 * j_np + 4 * math.floor(j_day_no / 1461)
j_day_no = j_day_no % 1461
if (j_day_no >= 366) then jy = jy + math.floor((j_day_no - 1) / 365) j_day_no =(j_day_no - 1) % 365 end
i = 1 while i <= 11 and j_day_no > daysMonth.jalali[i] do j_day_no = j_day_no - daysMonth.jalali[i] i = i + 1 end local jm = i local jd = j_day_no + 1
return {jy, jm, jd} end
local function getJalaliDateInTable() local dateTable = os.date("*t") return p.gregorianToJalali({args={dateTable.year, dateTable.month + 1, dateTable.day}}) end
function p.getCurrentJalaliYear() return getJalaliDateInTable()[1] end
function p.getCurrentJalaliMonth() return getJalaliDateInTable()[2] -1 end
-- Instructions about formatting: http://www.lua.org/pil/22.1.html function p.getFormattedCurrentJalaliDate(frame) local gd = os.date("%d") local gm = os.date("%m") local gy = os.date("%Y") local j = p.gregorianToJalali({args={gy, gm + 1, gd}}) return p.formatDate({args = {["format"] = frame.args["format"], j[1], j[2], j[3]}}) end
function p.formatDate(frame) -- پنجشنبه 13 شهریور 1393 17:09:00 ب.ظ frame.args["format"] = frame.args["format"] or "%A %d %B %Y %H:%M:%S %p" if type(frame.args["in"]) ~= "nil" then if string.lower(frame.args["in"]) == "iranian" then local j = p.jalaliToGregorian({args = {frame.args[1], frame.args[2], frame.args[3]}}) return os.date(frame.args["format"], os.time{year = j[1], month = j[2] - 1, day = j[3] + 1}) else return os.date(frame.args["format"], os.time{year = frame.args[1], month = frame.args[2] - 1, day = frame.args[3] + 1}) end else error("آرگومان in برای متد formatDate() یافت نشد.") end end
function p.getCurrentJalaliDay() return getJalaliDateInTable()[3] +1 end
function p.getDifferentTime(frame) return os.difftime(frame.args[1], frame.args[2]) end
return p