<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ar">
	<id>https://3rabica.org/index.php?action=history&amp;feed=atom&amp;title=%D9%88%D8%AD%D8%AF%D8%A9%3AHijri%2Fcore</id>
	<title>وحدة:Hijri/core - تاريخ المراجعة</title>
	<link rel="self" type="application/atom+xml" href="https://3rabica.org/index.php?action=history&amp;feed=atom&amp;title=%D9%88%D8%AD%D8%AF%D8%A9%3AHijri%2Fcore"/>
	<link rel="alternate" type="text/html" href="https://3rabica.org/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:Hijri/core&amp;action=history"/>
	<updated>2026-06-05T14:26:50Z</updated>
	<subtitle>تاريخ التعديل لهذه الصفحة في الويكي</subtitle>
	<generator>MediaWiki 1.43.7</generator>
	<entry>
		<id>https://3rabica.org/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:Hijri/core&amp;diff=2310&amp;oldid=prev</id>
		<title>عبد العزيز: حذف سطر تنقيح</title>
		<link rel="alternate" type="text/html" href="https://3rabica.org/index.php?title=%D9%88%D8%AD%D8%AF%D8%A9:Hijri/core&amp;diff=2310&amp;oldid=prev"/>
		<updated>2022-03-07T01:41:33Z</updated>

		<summary type="html">&lt;p&gt;حذف سطر تنقيح&lt;/p&gt;
&lt;p&gt;&lt;b&gt;صفحة جديدة&lt;/b&gt;&lt;/p&gt;&lt;div&gt;--[[--------------- luaHijri---------------------&lt;br /&gt;
by hubaishan&lt;br /&gt;
v0.5&lt;br /&gt;
locate at https://github.com/hubaishan/luaHijri&lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
--[[ ------------ C O N F I G U R A T I O N S ----------------------]]&lt;br /&gt;
--[[ As&lt;br /&gt;
local adjust_data = { [1443] = &lt;br /&gt;
	[5] = {2021,12,6},&lt;br /&gt;
	[7] = 1 }&lt;br /&gt;
	this means ad just start of month 5 of 1443 to 2021-12-06, and add one day to month 7 of 1443  &lt;br /&gt;
&lt;br /&gt;
]]&lt;br /&gt;
--local adjust_data = {} --adjust data in separate module&lt;br /&gt;
-- Gregorian Calender epoch used only for wertern calendar default value are in Italy some countries may differ&lt;br /&gt;
local gregorian_epoch = { jd = 2299161, y = 1582 , m = 10, d = 15}&lt;br /&gt;
-- sunday index can be 0 or 1&lt;br /&gt;
local wday_sunday = 0&lt;br /&gt;
-- day of year (1-1) index&lt;br /&gt;
local yday_1_1 = 0&lt;br /&gt;
-- @var int 1 to use adjusted Um Al-Qura algorithm, 2 to use Um Al-Qura algorithm, 0 use Hijri Tabular Algorithm&lt;br /&gt;
local hijri_mode = mw.loadData(&amp;#039;Module:Hijri/Configuration&amp;#039;).hijri_mode&lt;br /&gt;
--[[ ------------ C O N S T A N T S ----------------]]&lt;br /&gt;
--  the Um Al-Qura Calendar start year&lt;br /&gt;
local umstartyear = 1318&lt;br /&gt;
--  the Um Al-Qura Calendar end year&lt;br /&gt;
local umendyear = 1500&lt;br /&gt;
--  the Um Al-Qura Calendar start Julian day&lt;br /&gt;
local umstartjd = 2415140&lt;br /&gt;
-- the Um Al-Qura Calendar end  Julian day&lt;br /&gt;
local umendjd = 2479960&lt;br /&gt;
local UMDATA_COUNT = 2196&lt;br /&gt;
--[[ ------------ V A R S ----------------]]&lt;br /&gt;
local adjusted_umdata&lt;br /&gt;
local raw_umdata&lt;br /&gt;
--[[------------------- U T I L T Y   U S E F U L   F U N C T I O N S------------------------]]&lt;br /&gt;
local floor = math.floor&lt;br /&gt;
&lt;br /&gt;
local function round(number)&lt;br /&gt;
	return floor(number + 0.5)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function in_array( needle, haystack )&lt;br /&gt;
	if needle == nil then&lt;br /&gt;
		return false;&lt;br /&gt;
	end&lt;br /&gt;
	for n,v in ipairs( haystack ) do&lt;br /&gt;
		if v == needle then&lt;br /&gt;
			return n;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return false;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[------------------- C A L E N D A R   F U N C T I O N S------------------------]]&lt;br /&gt;
&lt;br /&gt;
--[[--- Data ---]]&lt;br /&gt;
local function gregorian2jd(year, month, day)&lt;br /&gt;
	-- from postgresql source&lt;br /&gt;
	local jd, century&lt;br /&gt;
	&lt;br /&gt;
	if year &amp;lt; 1 then&lt;br /&gt;
		year = year + 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if month &amp;gt; 2 then&lt;br /&gt;
		month = month + 1&lt;br /&gt;
		year = year + 4800&lt;br /&gt;
	else&lt;br /&gt;
		month = month + 13&lt;br /&gt;
		year = year + 4799&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	century = floor(year / 100)&lt;br /&gt;
&lt;br /&gt;
	return (year * 365 - 32167 + floor(year / 4) - century + floor(century / 4) + floor(7834 * month / 256) + day)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- load Umm al-Qura Calendar Data&lt;br /&gt;
-- Modified for MediaWiki&lt;br /&gt;
local function get_umdata(mode)&lt;br /&gt;
	mode = mode or hijri_mode&lt;br /&gt;
&lt;br /&gt;
	if mode==2 then&lt;br /&gt;
		if raw_umdata==nil or #raw_umdata==0 then		&lt;br /&gt;
			raw_umdata = mw.loadData(&amp;#039;Module:Hijri/umalqura data&amp;#039;)	&lt;br /&gt;
		end&lt;br /&gt;
		return raw_umdata&lt;br /&gt;
	elseif mode==1 then&lt;br /&gt;
		if adjusted_umdata == nil or #adjusted_umdata==0 then&lt;br /&gt;
			adjusted_umdata = mw.loadData(&amp;#039;Module:Hijri/adjusted data&amp;#039;)&lt;br /&gt;
		end&lt;br /&gt;
		return adjusted_umdata &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--- Hijri ---]]&lt;br /&gt;
&lt;br /&gt;
local function jd2hijri(julianday, mode)&lt;br /&gt;
    local mjd, ii, n, y, i&lt;br /&gt;
	local j, j1&lt;br /&gt;
	local hy, hm, hd, hz&lt;br /&gt;
	mode = mode or hijri_mode&lt;br /&gt;
	if (mode&amp;gt;0 and (julianday &amp;gt; umstartjd) and (julianday &amp;lt; umendjd)) then&lt;br /&gt;
		local umdata = get_umdata(mode)&lt;br /&gt;
		i = floor((julianday - 1948438) / 29.53056) - ((umstartyear - 1) * 12)&lt;br /&gt;
        mjd = julianday - 2400000&lt;br /&gt;
        if i&amp;lt;0 then i = 0 end&lt;br /&gt;
        for c = i, UMDATA_COUNT do&lt;br /&gt;
            if (umdata[c] &amp;gt; mjd) then&lt;br /&gt;
				i = c&lt;br /&gt;
                break&lt;br /&gt;
            end&lt;br /&gt;
		end&lt;br /&gt;
		ii = floor((i - 1) / 12) &lt;br /&gt;
		hy = umstartyear + ii&lt;br /&gt;
		hm = i - 12 * ii &lt;br /&gt;
		hd = mjd - umdata[i - 1] + 1&lt;br /&gt;
		hz = mjd - umdata[12 * ii]&lt;br /&gt;
	else&lt;br /&gt;
		j = julianday + 7666&lt;br /&gt;
		n = floor(j / 10631)&lt;br /&gt;
		j = j - (n * 10631)&lt;br /&gt;
		j1 = j&lt;br /&gt;
		y = floor(j / 354.36667)&lt;br /&gt;
		j = j - round(y * 354.36667)&lt;br /&gt;
		if j == 0 then&lt;br /&gt;
			y=y-1&lt;br /&gt;
			j = j1 - round(y * 354.36667)&lt;br /&gt;
			hz = j&lt;br /&gt;
			hd = j - 325&lt;br /&gt;
			hm = 12&lt;br /&gt;
		else&lt;br /&gt;
			hz = j - 1&lt;br /&gt;
			j = j + 29&lt;br /&gt;
			hm = floor((24 * j) / 709)&lt;br /&gt;
			hd = j -  floor(((709 * hm) / 24))&lt;br /&gt;
		end&lt;br /&gt;
		hy = (n * 30) + y + 1&lt;br /&gt;
		hy = hy - 5520&lt;br /&gt;
		if hy &amp;lt;= 0 then&lt;br /&gt;
			hy = hy - 1&lt;br /&gt;
		end&lt;br /&gt;
    end&lt;br /&gt;
	hz = hz + yday_1_1&lt;br /&gt;
    return hy, hm, hd, hz&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local function hijri2jd(hy, hm, hd, mode)&lt;br /&gt;
	mode = mode or hijri_mode&lt;br /&gt;
	local ii, i, n&lt;br /&gt;
	local j&lt;br /&gt;
	if (mode &amp;gt; 0 and hy &amp;gt;= umstartyear and hy &amp;lt;= umendyear) then&lt;br /&gt;
		local umdata = get_umdata(mode)&lt;br /&gt;
		ii = hy - umstartyear&lt;br /&gt;
		i = hm + 12 * ii&lt;br /&gt;
		j = hd + umdata[i - 1] - 1&lt;br /&gt;
		j = j + 2400000&lt;br /&gt;
	elseif (hy &amp;lt; -5499 or (hy == -5499 and hm &amp;lt; 8) or (hy == -5499 and hm == 8 and hd &amp;lt; 18)) then&lt;br /&gt;
		j = 0&lt;br /&gt;
	else&lt;br /&gt;
		hy = hy &amp;lt; 0 and (hy + 5520) or (hy + 5519)&lt;br /&gt;
		n = floor(hy / 30)&lt;br /&gt;
		j = (n * 10631) + round((hy - (n * 30)) * 354.36667)&lt;br /&gt;
		hm = hm - 1&lt;br /&gt;
		j = j + (hm * 29) + floor((hm + 1) / 2) + hd&lt;br /&gt;
		j = j- 7666&lt;br /&gt;
	end&lt;br /&gt;
	return j&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hijri_days_in_month(year, month, mode)&lt;br /&gt;
	mode = mode or hijri_mode&lt;br /&gt;
	local t = 29&lt;br /&gt;
	if mode&amp;gt;0 and year &amp;gt;= umstartyear and year &amp;lt;= umendyear then&lt;br /&gt;
		local i = (year-umstartyear)*12 + month -1&lt;br /&gt;
		local umdata = get_umdata(mode)&lt;br /&gt;
		t = umdata[i + 1] - umdata[i]&lt;br /&gt;
	else&lt;br /&gt;
		if month == 12 then&lt;br /&gt;
			if year &amp;lt; 0 then&lt;br /&gt;
				year = year + 5521&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if round((year % 30) * 0.36667) &amp;gt; round(((year - 1) % 30) * 0.36667) then&lt;br /&gt;
				t = 30&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			t = 29 + (month % 2);&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hijri_isleap(year, mode)&lt;br /&gt;
	mode = mode or hijri_mode&lt;br /&gt;
	local l&lt;br /&gt;
	if mode&amp;gt;0 and year &amp;gt;= umstartyear and year &amp;lt;= umendyear then&lt;br /&gt;
		local umdata = get_umdata(mode)&lt;br /&gt;
		local ii = year - umstartyear&lt;br /&gt;
		l = ((umdata[12 * (ii + 1)] - umdata[12 * ii]) &amp;gt; 354) and true or false&lt;br /&gt;
	else&lt;br /&gt;
		if year &amp;lt; 0 then&lt;br /&gt;
			year = year + 5521;&lt;br /&gt;
		end&lt;br /&gt;
		l = (round((year % 30) * 0.36667) &amp;gt; round(((year - 1) % 30) * 0.36667)) and true or false&lt;br /&gt;
	end&lt;br /&gt;
	return l&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hijri_yday(year,month,day,mode)&lt;br /&gt;
    local ii&lt;br /&gt;
	mode = mode or hijri_mode&lt;br /&gt;
	if (mode&amp;gt;0 and year &amp;gt;= umstartyear and year &amp;lt;= umendyear) then&lt;br /&gt;
		local umdata = get_umdata(mode)&lt;br /&gt;
		ii = year - umstartyear&lt;br /&gt;
		return umdata[(12 * ii) + month -1] - umdata[12 * ii] + day - 1 + yday_1_1&lt;br /&gt;
	else&lt;br /&gt;
		return select(month, 0,30,59,89,118,148,177,207,236,266,295,325) + day - 1 + yday_1_1 &lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hijri_check(year,month,day,mode,may_adjusted)&lt;br /&gt;
	if month &amp;lt; 1 or month &amp;gt; 12 then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if day &amp;lt; 1 or day &amp;gt; 30 then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if not may_adjusted and day &amp;gt; hijri_days_in_month(year,month,mode) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
--[[--- Unix and wday---]]&lt;br /&gt;
&lt;br /&gt;
local function jd2unix(jd)&lt;br /&gt;
	-- 2440588 -- J.D. of 1.1.1970&lt;br /&gt;
	if jd == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	return ((jd - 2440588) * 24 * 3600)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function unix2jd(unix)&lt;br /&gt;
	if unix == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	return floor(unix/(24 * 3600)) + 2440588&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--returns wday number sunday=wday_sunday&lt;br /&gt;
local function jd2wday(jd)&lt;br /&gt;
	jd = jd + 1&lt;br /&gt;
	jd = jd % 7&lt;br /&gt;
	if (jd&amp;lt;0) then&lt;br /&gt;
		jd = jd + 7&lt;br /&gt;
	end&lt;br /&gt;
	return jd + wday_sunday&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--- Gregorian ---]]&lt;br /&gt;
&lt;br /&gt;
local function jd2gregorian(jd)&lt;br /&gt;
	-- inspired by postgresql function&lt;br /&gt;
	local julian, quad, extra, y&lt;br /&gt;
	local year,month,day&lt;br /&gt;
	julian = jd + 32044&lt;br /&gt;
	&lt;br /&gt;
	quad = floor(julian / 146097)&lt;br /&gt;
	&lt;br /&gt;
	extra = (julian - quad * 146097) * 4 + 3&lt;br /&gt;
	julian = julian + 60 + quad * 3 + floor(extra / 146097)&lt;br /&gt;
	quad = floor(julian / 1461)&lt;br /&gt;
	julian = julian - quad * 1461&lt;br /&gt;
	y = floor(julian * 4 / 1461)&lt;br /&gt;
	&lt;br /&gt;
	if (y ~= 0) then&lt;br /&gt;
		julian = ((julian + 305) % 365) + 123&lt;br /&gt;
	else&lt;br /&gt;
		julian = ((julian + 306) % 366) + 123&lt;br /&gt;
	end&lt;br /&gt;
	y = y + quad * 4;&lt;br /&gt;
	year = y - 4800;&lt;br /&gt;
	&lt;br /&gt;
	quad = floor(julian * 2141 / 65536)&lt;br /&gt;
	day = julian - floor(7834 * quad / 256)&lt;br /&gt;
	month = (quad + 10) % 12 + 1&lt;br /&gt;
&lt;br /&gt;
	if (year&amp;lt;1) then&lt;br /&gt;
		year = year-1&lt;br /&gt;
	end&lt;br /&gt;
	return year,month,day&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function gre_isleap(year)&lt;br /&gt;
	if year&amp;lt;1 then year=year+1 end&lt;br /&gt;
	return (year % 4) == 0 and ((year % 100) ~= 0 or (year % 400) == 0)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function gre_yday(year,month,day)&lt;br /&gt;
	if gre_isleap(year) then&lt;br /&gt;
		return  select(month,0,31,60,91,121,152,182,213,244,274,305,335) + day - 1 + yday_1_1&lt;br /&gt;
	else&lt;br /&gt;
		return  select(month,0,31,59,90,120,151,181,212,243,273,304,334) + day - 1 + yday_1_1&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function gre_days_in_month(year, month)&lt;br /&gt;
	if month == 2 and gre_isleap(year) then&lt;br /&gt;
		return 29&lt;br /&gt;
	else&lt;br /&gt;
		return select(month,31,28,31,30,31,30,31,31,30,31,30,31)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function gre_check(year,month,day)&lt;br /&gt;
	if month &amp;lt; 1 or month &amp;gt; 12 then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if day &amp;lt; 1 or day &amp;gt; gre_days_in_month(year,month) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
--[[--- Julian ---]]&lt;br /&gt;
&lt;br /&gt;
local function jd2julian(jd)&lt;br /&gt;
	local year, month, day&lt;br /&gt;
	local temp, dayofYear&lt;br /&gt;
&lt;br /&gt;
	temp = jd * 4 + (32083 * 4 - 1)&lt;br /&gt;
&lt;br /&gt;
	year = floor(temp / 1461)&lt;br /&gt;
	dayofYear = floor((temp % 1461) / 4) + 1&lt;br /&gt;
&lt;br /&gt;
	temp = dayofYear * 5 - 3&lt;br /&gt;
	month = floor(temp / 153)&lt;br /&gt;
	day = floor((temp % 153) / 5) + 1&lt;br /&gt;
&lt;br /&gt;
	if (month &amp;lt; 10) then&lt;br /&gt;
		month = month + 3&lt;br /&gt;
	else&lt;br /&gt;
		year = year + 1&lt;br /&gt;
		month = month - 9&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	year = year - 4800&lt;br /&gt;
	if (year &amp;lt; 1) then&lt;br /&gt;
		year = year -1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return year, month, day&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function julian2jd(year,month,day)&lt;br /&gt;
	if year&amp;lt;0 then&lt;br /&gt;
		year = year + 4801&lt;br /&gt;
	else&lt;br /&gt;
		year = year + 4800&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if month &amp;gt; 2 then&lt;br /&gt;
		month = month -3&lt;br /&gt;
	else&lt;br /&gt;
		month = month + 9&lt;br /&gt;
		year = year - 1&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return (floor((year * 1461) / 4) + floor((month * 153 + 2) / 5) + day - 32083)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function julian_isleap(year)&lt;br /&gt;
	if year &amp;lt; 1 then year = year + 1 end&lt;br /&gt;
	return (year % 4) == 0&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function julian_yday(year,month,day)&lt;br /&gt;
	if julian_isleap(year) then&lt;br /&gt;
		return  select(month,0,31,60,91,121,152,182,213,244,274,305,335) + day - 1 + yday_1_1&lt;br /&gt;
	else&lt;br /&gt;
		return  select(month,0,31,59,90,120,151,181,212,243,273,304,334) + day - 1 + yday_1_1&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function julian_days_in_month(year, month)&lt;br /&gt;
	if month == 2 and julian_isleap(year) then&lt;br /&gt;
		return 29&lt;br /&gt;
	else&lt;br /&gt;
		return select(month,31,28,31,30,31,30,31,31,30,31,30,31)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function julian_check(year,month,day)&lt;br /&gt;
	if month &amp;lt; 1 or month &amp;gt; 12 then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	if day &amp;lt; 1 or day &amp;gt; julian_days_in_month(year,month) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[--- Convertion ---]]&lt;br /&gt;
&lt;br /&gt;
-- Return Hijri Date from Gregorian date&lt;br /&gt;
local function gregorian2hijri(gyear, gmonth, gday)&lt;br /&gt;
	return jd2hijri(gregorian2jd(gyear, gmonth, gday))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function hijri2gregorian(hyear, hmonth, hday)&lt;br /&gt;
	return jd2gregorian(hijri2jd(hyear, hmonth, hday))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[------------------- D A T E   C L A S S ------------------------]]&lt;br /&gt;
&lt;br /&gt;
local datePrototype = {}&lt;br /&gt;
&lt;br /&gt;
-- Set julianDay&lt;br /&gt;
function datePrototype:set_jd(arg_jd)&lt;br /&gt;
	if self.p.type == &amp;#039;hijri&amp;#039; then&lt;br /&gt;
		self.p.year, self.p.month, self.p.day, self.p.yday = jd2hijri(arg_jd,self.p.mode)&lt;br /&gt;
		self.p.jd = arg_jd&lt;br /&gt;
	elseif self.p.type == &amp;#039;gregorian&amp;#039; or (self.p.type == &amp;#039;western&amp;#039; and arg_jd &amp;gt;= gregorian_epoch.jd ) then&lt;br /&gt;
		self.p.year, self.p.month, self.p.day = jd2gregorian(arg_jd)&lt;br /&gt;
		self.p.jd, self.p.yday = arg_jd, nil&lt;br /&gt;
	elseif self.p.type == &amp;#039;julian&amp;#039; or (self.p.type == &amp;#039;western&amp;#039; and arg_jd &amp;lt; gregorian_epoch.jd ) then&lt;br /&gt;
		self.p.year, self.p.month, self.p.day = jd2julian(arg_jd)&lt;br /&gt;
		self.p.jd, self.p.yday = arg_jd, nil&lt;br /&gt;
	end&lt;br /&gt;
	self.p.wday, self.p.month_days, self.p.leap_year  = nil, nil, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function datePrototype:get_jd()&lt;br /&gt;
	if self.p.jd ~= nil then&lt;br /&gt;
		return self.p.jd&lt;br /&gt;
	elseif self.p.year and self.p.month and self.p.day then&lt;br /&gt;
		self:set_date(self.p.year,self.p.month,self.p.day)&lt;br /&gt;
	else&lt;br /&gt;
		local t=os.date(&amp;quot;*t&amp;quot;)&lt;br /&gt;
		if self.p.type==&amp;#039;gregorian&amp;#039; then&lt;br /&gt;
			self.p.year, self.p.month, self.p.day, self.p.wday, self.p.yday = t.year, t.month, t.day, t.wday - 1 + wday_sunday, t.yday&lt;br /&gt;
			self.p.jd = gregorian2jd(self.p.year, self.p.month, self.p.day)&lt;br /&gt;
		else&lt;br /&gt;
			self:from_gregorian(t.year,t.month,t.day)&lt;br /&gt;
			self.p.wday = t.wday -1 + wday_sunday&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return self.p.jd&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function datePrototype:set_timestamp(arg_tm)&lt;br /&gt;
	if self.p.timestamp == arg_tm then&lt;br /&gt;
		return&lt;br /&gt;
	end&lt;br /&gt;
	self.p.timestamp = arg_tm&lt;br /&gt;
	self:set_jd(unix2jd(arg_tm))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
    -- adjust type of western calendar&lt;br /&gt;
local function adj_type(type,year,month,day)&lt;br /&gt;
	if type == &amp;#039;western&amp;#039; then&lt;br /&gt;
		if year&amp;gt;gregorian_epoch.y or (year==gregorian_epoch.y and month&amp;gt;gregorian_epoch.m) or (year==gregorian_epoch.y and month == gregorian_epoch.m and day&amp;gt;=gregorian_epoch.d) then&lt;br /&gt;
			type=&amp;#039;gregorian&amp;#039;&lt;br /&gt;
		else&lt;br /&gt;
			type = &amp;#039;julian&amp;#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return type&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	-- Check the Date&lt;br /&gt;
local function check_date(ctype,cmode,year,month,day,may_adjusted)&lt;br /&gt;
	local type = adj_type(ctype,year,month,day)&lt;br /&gt;
	if month &amp;lt;1 or month &amp;gt;12 or day &amp;lt;1 or day &amp;gt;31 then&lt;br /&gt;
		return false&lt;br /&gt;
	elseif type == &amp;#039;hijri&amp;#039; then&lt;br /&gt;
		if day &amp;gt; 30 or (not may_adjusted and day&amp;gt; hijri_days_in_month(year,month,cmode)) then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	elseif day &amp;gt; select(month,31,29,31,30,31,30,31,31,30,31,30,31) then &lt;br /&gt;
		return false&lt;br /&gt;
	elseif month == 2 and day == 29 then&lt;br /&gt;
		if (((year % 4) ~= 0) or (type == &amp;#039;gregorian&amp;#039;  and (year % 100) == 0 and (year % 400) ~= 0)) then&lt;br /&gt;
			return false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
	-- Set Date&lt;br /&gt;
	-- may_adjusted argument used in Hijri only to accept any 30 day of any month&lt;br /&gt;
function datePrototype:set_date(year,month,day,may_adjusted)&lt;br /&gt;
	if not check_date(self.p.type, self.p.mode, year, month, day, may_adjusted) then&lt;br /&gt;
		error(&amp;quot;Invalid Date&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	local type=adj_type(self.p.type,year,month,day)&lt;br /&gt;
	if type == &amp;#039;hijri&amp;#039; then&lt;br /&gt;
		self.p.jd = hijri2jd(year,month,day,self.p.mode)&lt;br /&gt;
	elseif type == &amp;#039;gregorian&amp;#039; then&lt;br /&gt;
		self.p.jd = gregorian2jd(year,month,day)&lt;br /&gt;
	elseif type == &amp;#039;julian&amp;#039; then&lt;br /&gt;
		self.p.jd = julian2jd(year,month,day)&lt;br /&gt;
	end&lt;br /&gt;
	self.p.year, self.p.month, self.p.day = year,month,day&lt;br /&gt;
	self.p.wday, self.p.month_days, self.p.leap_year, self.p.yday  = nil, nil, nil, nil&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Convert date from hijri&lt;br /&gt;
function datePrototype:from_hijri(year,month,day,wday,mode)&lt;br /&gt;
	mode = mode or self.p.mode&lt;br /&gt;
	local jd = hijri2jd(year,month,day,mode)&lt;br /&gt;
	if wday and wday &amp;lt;= 6 and wday &amp;gt;=0 then&lt;br /&gt;
		local jd_weekday = jd2wday(jd)&lt;br /&gt;
		local differ = wday - jd_weekday&lt;br /&gt;
&lt;br /&gt;
		if differ &amp;lt; - 4 then&lt;br /&gt;
			jd = jd + (differ + 7)&lt;br /&gt;
		elseif differ &amp;gt; -3 and differ &amp;lt; 3 then&lt;br /&gt;
			jd = jd + differ&lt;br /&gt;
		elseif differ &amp;gt; 4 then&lt;br /&gt;
			jd = jd + (differ - 7)&lt;br /&gt;
		else&lt;br /&gt;
			error(&amp;quot;Weekday is very far from Hijri date&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	if self.p.type == &amp;#039;hijri&amp;#039; and check_date(self.p.type, self.p.mode, year,month,day,true) then&lt;br /&gt;
		self.p.year,self.p.month,self.p.day,self.p.jd=year,month,day,jd&lt;br /&gt;
		self.p.wday, self.p.month_days, self.p.leap_year, self.p.yday  = nil, nil, nil, nil&lt;br /&gt;
	else&lt;br /&gt;
		self:set_jd(jd)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Convert date from Gregorian&lt;br /&gt;
function datePrototype:from_gregorian(year,month,day)&lt;br /&gt;
	self:set_jd(gregorian2jd(year,month,day))&lt;br /&gt;
end&lt;br /&gt;
-- Convert date from Julian&lt;br /&gt;
function datePrototype:from_julian(year,month,day)&lt;br /&gt;
	self:set_jd(julian2jd(year,month,day))&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Convert date from Western&lt;br /&gt;
function datePrototype:from_western(year,month,day)&lt;br /&gt;
	if year&amp;gt;gregorian_epoch.y or (year==gregorian_epoch.y and month&amp;gt;gregorian_epoch.m) or (year==gregorian_epoch.y and month == gregorian_epoch.m and day&amp;gt;=gregorian_epoch.d) then&lt;br /&gt;
		self:set_jd(gregorian2jd(year,month,day))&lt;br /&gt;
	else&lt;br /&gt;
		self:set_jd(julian2jd(year,month,day))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- set type of calendar&lt;br /&gt;
function datePrototype:set_type(arg_type)&lt;br /&gt;
	local new_type,new_mode&lt;br /&gt;
	arg_type = string.lower(arg_type)&lt;br /&gt;
	if in_array(arg_type, {&amp;#039;hijri&amp;#039;, &amp;#039;hijri_adjusted_umalqura&amp;#039;, &amp;#039;hijri_umalqura&amp;#039;, &amp;#039;hijri_tabular&amp;#039;, &amp;#039;gregorian&amp;#039;, &amp;#039;julian&amp;#039;, &amp;#039;western&amp;#039;}) then&lt;br /&gt;
		if string.sub(arg_type,1,5) == &amp;#039;hijri&amp;#039; then&lt;br /&gt;
			new_type = &amp;#039;hijri&amp;#039;&lt;br /&gt;
			if arg_type == &amp;#039;hijri_umalqura&amp;#039; then&lt;br /&gt;
				new_mode = 2&lt;br /&gt;
			elseif arg_type == &amp;#039;hijri_tabular&amp;#039; then&lt;br /&gt;
				new_mode = 0&lt;br /&gt;
			else&lt;br /&gt;
				new_mode = 1&lt;br /&gt;
			end&lt;br /&gt;
		else&lt;br /&gt;
			new_type = arg_type&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		if new_type ~= self.p.type or new_mode ~= self.p.mode then&lt;br /&gt;
			self.p.type = new_type&lt;br /&gt;
			self.p.mode = new_mode&lt;br /&gt;
			if self.p.jd then&lt;br /&gt;
				self:set_jd(self.p.jd)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	else&lt;br /&gt;
		error(&amp;#039;bad calendar type&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function datePrototype:get_value(key)&lt;br /&gt;
	if not self.p[key] then&lt;br /&gt;
		local jd = self:get_jd() -- to init calendar if not&lt;br /&gt;
		if key==&amp;#039;wday&amp;#039; then&lt;br /&gt;
			self.p.wday = jd2wday(jd)&lt;br /&gt;
		elseif key == &amp;#039;timestamp&amp;#039; then&lt;br /&gt;
			self.p.timestamp = jd2unix(jd)&lt;br /&gt;
		else&lt;br /&gt;
			if self.p.type==&amp;#039;hijri&amp;#039; and key==&amp;#039;leap_year&amp;#039; then&lt;br /&gt;
				self.p.leap_year = hijri_isleap(self.p.year,self.p.mode)&lt;br /&gt;
			elseif self.p.type == &amp;#039;gregorian&amp;#039; or (self.p.type == &amp;#039;western&amp;#039; and self.p.year &amp;gt; gregorian_epoch.y ) then&lt;br /&gt;
				self.p.leap_year = gre_isleap(self.p.year)&lt;br /&gt;
			elseif self.p.type == &amp;#039;julian&amp;#039; or (self.p.type == &amp;#039;western&amp;#039; and self.p.year &amp;lt;= gregorian_epoch.y ) then&lt;br /&gt;
				self.p.leap_year = julian_isleap(self.p.year)&lt;br /&gt;
			end&lt;br /&gt;
	&lt;br /&gt;
			if key == &amp;#039;yday&amp;#039; then&lt;br /&gt;
				if  self.p.type ~= &amp;#039;hijri&amp;#039; then&lt;br /&gt;
					if self.p.leap_year then&lt;br /&gt;
						self.p.yday =  select(self.p.month,0,31,60,91,121,152,182,213,244,274,305,335) + self.p.day - 1 + yday_1_1&lt;br /&gt;
					else&lt;br /&gt;
						self.p.yday =  select(self.p.month,0,31,59,90,120,151,181,212,243,273,304,334) + self.p.day - 1 + yday_1_1&lt;br /&gt;
					end&lt;br /&gt;
						&lt;br /&gt;
				elseif self.p.type == &amp;#039;hijri&amp;#039; then&lt;br /&gt;
					self.p.yday = hijri_yday(self.p.year,self.p.month,self.p.day,self.p.mode)&lt;br /&gt;
				end&lt;br /&gt;
			elseif key == &amp;#039;month_days&amp;#039; then&lt;br /&gt;
				if self.p.type==&amp;#039;hijri&amp;#039; then&lt;br /&gt;
					self.p.month_days = hijri_days_in_month(self.p.year,self.p.month,self.p.mode)&lt;br /&gt;
				else&lt;br /&gt;
					if self.p.month == 2 and self.p.leap_year then&lt;br /&gt;
						self.p.month_days = 29&lt;br /&gt;
					else&lt;br /&gt;
						self.p.month_days = select(self.p.month,31,28,31,30,31,30,31,31,30,31,30,31)&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return self.p[key]&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- add interval to date&lt;br /&gt;
function datePrototype:add(y, m, d)&lt;br /&gt;
	y,m,d = tonumber(y) or 0,tonumber(m) or 0,tonumber(d) or 0&lt;br /&gt;
	local jd = self:get_jd()&lt;br /&gt;
	if y==0 and m == 0 then&lt;br /&gt;
		jd = jd + d&lt;br /&gt;
	else&lt;br /&gt;
		local year,month,day=self.p.year + y, self.p.month + m, self.p.day + d&lt;br /&gt;
		if self.p.type == &amp;#039;hijri&amp;#039; then&lt;br /&gt;
			jd = hijri2jd(year,month,day,self.p.mode)&lt;br /&gt;
		elseif self.p.type == &amp;#039;gregorian&amp;#039; then&lt;br /&gt;
			jd = gregorian2jd(year,month,day)&lt;br /&gt;
		elseif self.p.type == &amp;#039;julian&amp;#039; then&lt;br /&gt;
			jd = julian2jd(year,month,day)&lt;br /&gt;
		elseif self.p.type == &amp;#039;western&amp;#039; then&lt;br /&gt;
			if self.p.jd &amp;gt;= gregorian_epoch.jd then&lt;br /&gt;
				jd = gregorian2jd(year,month,day)&lt;br /&gt;
				if jd&amp;lt; gregorian_epoch.jd then&lt;br /&gt;
					jd = julian2jd(year,month,day)&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				jd = julian2jd(year,month,day)&lt;br /&gt;
				if jd&amp;gt;= gregorian_epoch.jd then&lt;br /&gt;
					jd = gregorian2jd(year,month,day)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if jd ~= self.p.jd then&lt;br /&gt;
		self:set_jd(jd)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function datePrototype:iso()&lt;br /&gt;
	local ret, str, jd = &amp;#039;&amp;#039;, &amp;#039;&amp;#039;, self:get_jd()&lt;br /&gt;
	local year, month, day&lt;br /&gt;
&lt;br /&gt;
	if self.p.type==&amp;#039;gregorian&amp;#039; then&lt;br /&gt;
		year, month, day = self.p.year, self.p.month, self.p.day&lt;br /&gt;
	else&lt;br /&gt;
		year, month, day = jd2gregorian(jd)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if year &amp;lt; 0 then&lt;br /&gt;
		year = year - 1&lt;br /&gt;
		ret = &amp;#039;-&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	str = tostring(math.abs(year))&lt;br /&gt;
	return ret .. string.rep(&amp;#039;0&amp;#039;, 4 - #str) .. str .. &amp;#039;-&amp;#039; .. ((month&amp;lt;10) and &amp;#039;0&amp;#039; or &amp;#039;&amp;#039;) .. month .. &amp;#039;-&amp;#039; .. ((day&amp;lt;10) and &amp;#039;0&amp;#039; or &amp;#039;&amp;#039;) .. day&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function DateWrapper(dt)&lt;br /&gt;
	local t = {}&lt;br /&gt;
	t.p = {}&lt;br /&gt;
	local rop = {&lt;br /&gt;
		type = false,&lt;br /&gt;
		mode = true,&lt;br /&gt;
		jd  = false,&lt;br /&gt;
		timestamp = false,&lt;br /&gt;
		year = true,&lt;br /&gt;
		month = true,&lt;br /&gt;
		day = true,&lt;br /&gt;
		wday = true,&lt;br /&gt;
		yday = true,&lt;br /&gt;
		month_days = true,&lt;br /&gt;
		leap_year  = true&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	local mt = {&lt;br /&gt;
		__index = function ( tt, k )&lt;br /&gt;
			assert( t == tt )&lt;br /&gt;
			local v = tt.p[k] or  datePrototype[k]&lt;br /&gt;
			if v == nil and rop[k] ~=nil then&lt;br /&gt;
				v = tt:get_value(k)&lt;br /&gt;
			end&lt;br /&gt;
			return v&lt;br /&gt;
		end,&lt;br /&gt;
		__newindex = function ( t, k, v )&lt;br /&gt;
			if rop[k] then&lt;br /&gt;
				error(&amp;quot;Attempt to modify read-only property&amp;quot;)&lt;br /&gt;
			elseif k == &amp;#039;jd&amp;#039; then&lt;br /&gt;
				t:set_jd(v)&lt;br /&gt;
			elseif k == &amp;#039;type&amp;#039; then&lt;br /&gt;
				t:set_type(v)&lt;br /&gt;
			elseif k == &amp;#039;timestamp&amp;#039; then&lt;br /&gt;
				t:set_timestamp(v)&lt;br /&gt;
			else&lt;br /&gt;
				rawset(t, k, v)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	}&lt;br /&gt;
	-- This is just to make setmetatable() fail&lt;br /&gt;
	mt.__metatable = mt&lt;br /&gt;
&lt;br /&gt;
	return setmetatable( t, mt )&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function Date(arg_type, arg_jd, arg_month, arg_day)&lt;br /&gt;
	local d = DateWrapper({})&lt;br /&gt;
	-- process argument&lt;br /&gt;
	d:set_type(arg_type)&lt;br /&gt;
&lt;br /&gt;
	if arg_jd and arg_month and arg_day  then&lt;br /&gt;
		d:set_date(arg_jd, arg_month, arg_day)&lt;br /&gt;
	elseif arg_jd then&lt;br /&gt;
		d:set_jd(arg_jd)&lt;br /&gt;
	end&lt;br /&gt;
	return d&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
return {&lt;br /&gt;
	gregorian2jd = gregorian2jd,&lt;br /&gt;
	jd2hijri = jd2hijri,&lt;br /&gt;
	hijri2jd = hijri2jd,&lt;br /&gt;
	hijri_days_in_month = hijri_days_in_month,&lt;br /&gt;
	hijri_isleap = hijri_isleap,&lt;br /&gt;
	hijri_yday = hijri_yday,&lt;br /&gt;
	jd2unix = jd2unix,&lt;br /&gt;
	unix2jd = unix2jd,&lt;br /&gt;
	jd2wday = jd2wday,&lt;br /&gt;
	jd2gregorian = jd2gregorian,&lt;br /&gt;
	gre_isleap = gre_isleap,&lt;br /&gt;
	gre_yday = gre_yday,&lt;br /&gt;
	gre_days_in_month = gre_days_in_month,&lt;br /&gt;
	jd2julian = jd2julian,&lt;br /&gt;
	julian2jd = julian2jd,&lt;br /&gt;
	julian_isleap = julian_isleap,&lt;br /&gt;
	julian_yday = julian_yday,&lt;br /&gt;
	julian_days_in_month = julian_days_in_month,&lt;br /&gt;
	gregorian2hijri = gregorian2hijri,&lt;br /&gt;
	hijri2gregorian = hijri2gregorian,&lt;br /&gt;
	Date = Date,&lt;br /&gt;
	hijri_check = hijri_check,&lt;br /&gt;
	gre_check = gre_check,&lt;br /&gt;
	julian_check = julian_check&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>عبد العزيز</name></author>
	</entry>
</feed>