مسابقه دانش‌دخت
اسلامیکال از تاریخ ۱۵ دی تا ۲۰ بهمن، میزبان یک همایه با موضوع زنان است. شما می‌توانید در مسابقه مقاله‌نویسی دانش‌دخت، شرکت کنید و با نگارش مقاله، از جوایز آن بهره‌مند باشید. اگر به موضوعات مربوط با زنان علاقه‌مندید، این فرصت را از دست ندهید. فهرستی از مقالات پیشنهادی جهت ایجاد یا ویرایش در اینجا وجود دارد.

پودمان:Iranian calendar/library

از اسلامیکال
نسخهٔ تاریخ ‏۲۵ ژانویهٔ ۲۰۲۳، ساعت ۱۵:۴۷ توسط Mojtabakd (بحث | مشارکت‌ها) (ایجاد پودمان)
(تفاوت) → نسخهٔ قدیمی‌تر | نمایش نسخهٔ فعلی (تفاوت) | نسخهٔ جدیدتر ← (تفاوت)
پرش به ناوبری پرش به جستجو

توضیحات این پودمان می‌تواند در پودمان: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)
	-- پنج‌شنبه ۱۳ شهریور ۱۳۹۳ ۱۷:۰۹:۰۰ ب.ظ
	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