پودمان:Date

از ویکی‌خبر، مرجع خبری آزاد
نماد توضیحات توضیحات پودمان[نمایش] [ویرایش] [تاریخچه] [پاکسازی]

Usage

date Function

{{#invoke:date|date|format|date type (dafault: gregorian)|timezone (dafault: UTC)|language (dafault: en)|timestamp (dafault: current timestamp)}}

time Function

Returns current timestamp in UTC.
{{#invoke:date|time}}

Examples

{{#invoke:date|date|l j F Y h:i:s A|gregorian|UTC|en}}
outputs: Thursday 25 April 2024 09:40:13 AM

{{#invoke:date|date|l j F Y h:i:s A|gregorian|UTC|fa}}
outputs: پنج‌شنبه ۲۵ آوریل ۲۰۲۴ ۰۹:۴۰:۱۳ ق.ظ.

{{#invoke:date|date|l j F Y h:i:s A|solar|UTC|en}}
outputs: Thursday 6 Khordad 1403 09:40:13 AM

{{#invoke:date|date|l j F Y h:i:s A|solar|UTC|fa}}
outputs: پنج‌شنبه ۶ خرداد ۱۴۰۳ ۰۹:۴۰:۱۳ ق.ظ.

{{#invoke:date|date|l j F Y h:i:s A|gregorian|Asia/Tehran|en}}
outputs: Thursday 25 April 2024 02:10:13 PM

{{#invoke:date|date|l j F Y h:i:s A|gregorian|Asia/Tehran|fa}}
outputs: پنج‌شنبه ۲۵ آوریل ۲۰۲۴ ۰۲:۱۰:۱۳ ب.ظ.

{{#invoke:date|date|l j F Y h:i:s A|solar|Asia/Tehran|en}}
outputs: Thursday 6 Khordad 1403 02:10:13 PM

{{#invoke:date|date|l j F Y h:i:s A|solar|Asia/Tehran|fa}}
outputs: پنج‌شنبه ۶ خرداد ۱۴۰۳ ۰۲:۱۰:۱۳ ب.ظ.

{{#invoke:date|date|l j F Y h:i:s A|gregorian|UTC|en|1416586577}}
outputs: Friday 21 November 2014 04:16:17 PM

{{#invoke:date|date|l j F Y h:i:s A|gregorian|UTC|fa|1416586577}}
outputs: جمعه ۲۱ نوامبر ۲۰۱۴ ۰۴:۱۶:۱۷ ب.ظ.

{{#invoke:date|date|l j F Y h:i:s A|solar|UTC|en|1416586577}}
outputs: Friday 30 Aban 1393 04:16:17 PM

{{#invoke:date|date|l j F Y h:i:s A|solar|UTC|fa|1416586577}}
outputs: جمعه ۳۰ آبان ۱۳۹۳ ۰۴:۱۶:۱۷ ب.ظ.

{{#invoke:date|date|l j F Y h:i:s A|gregorian|Asia/Tehran|en|1416586577}}
outputs: Friday 21 November 2014 07:46:17 PM

{{#invoke:date|date|l j F Y h:i:s A|gregorian|Asia/Tehran|fa|1416586577}}
outputs: جمعه ۲۱ نوامبر ۲۰۱۴ ۰۷:۴۶:۱۷ ب.ظ.

{{#invoke:date|date|l j F Y h:i:s A|solar|Asia/Tehran|en|1416586577}}
outputs: Friday 30 Aban 1393 07:46:17 PM

{{#invoke:date|date|l j F Y h:i:s A|solar|Asia/Tehran|fa|1416586577}}
outputs: جمعه ۳۰ آبان ۱۳۹۳ ۰۷:۴۶:۱۷ ب.ظ.

{{#invoke:date|date|l j F Y h:i:s A|gregorian|UTC|en|{{#invoke:date|time}}}}
outputs: Thursday 25 April 2024 09:40:13 AM

{{#invoke:date|date|l j F Y h:i:s A|gregorian|UTC|fa|{{#invoke:date|time}}}}
outputs: پنج‌شنبه ۲۵ آوریل ۲۰۲۴ ۰۹:۴۰:۱۳ ق.ظ.

{{#invoke:date|date|l j F Y h:i:s A|solar|UTC|en|{{#invoke:date|time}}}}
outputs: Thursday 6 Khordad 1403 09:40:13 AM

{{#invoke:date|date|l j F Y h:i:s A|solar|UTC|fa|{{#invoke:date|time}}}}
outputs: پنج‌شنبه ۶ خرداد ۱۴۰۳ ۰۹:۴۰:۱۳ ق.ظ.

{{#invoke:date|date|l j F Y h:i:s A|gregorian|Asia/Tehran|en|{{#invoke:date|time}}}}
outputs: Thursday 25 April 2024 02:10:13 PM

{{#invoke:date|date|l j F Y h:i:s A|gregorian|Asia/Tehran|fa|{{#invoke:date|time}}}}
outputs: پنج‌شنبه ۲۵ آوریل ۲۰۲۴ ۰۲:۱۰:۱۳ ب.ظ.

{{#invoke:date|date|l j F Y h:i:s A|solar|Asia/Tehran|en|{{#invoke:date|time}}}}
outputs: Thursday 6 Khordad 1403 02:10:13 PM

{{#invoke:date|date|l j F Y h:i:s A|solar|Asia/Tehran|fa|{{#invoke:date|time}}}}
outputs: پنج‌شنبه ۶ خرداد ۱۴۰۳ ۰۲:۱۰:۱۳ ب.ظ.

--
-- Written by [[User:Mjbmr]]
-- 

local p = {}

p.weekdays1 = {}
p.weekdays1['en'] = {"Sunday","Monday","Tuesday","Wednday","Thursday","Friday","Saturday"}
p.weekdays1['fa'] = {"یکشنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه"}

p.months1 = {}
p.months1['gregorian'] = {}
p.months1['gregorian']['en'] = {"January","February","March","April","May","June","July","August","September","October","November","December"}
p.months1['gregorian']['fa'] = {"ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"}

p.months1['solar'] = {}
p.months1['solar']['en'] = {"Farvardin","Khordad","Ordibehesht","Tir","Mordad","Shahrivar","Mehr","Aban","Azar","Day","Bahman","Esfand"}
p.months1['solar']['fa'] = {"فروردین","خرداد","اردیبهشت","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"}

p.months2 = {}
p.months2['gregorian'] = {}
p.months2['gregorian']['en'] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}
p.months2['gregorian']['fa'] = {"ژانویه","فوریه","مارس","آوریل","مه","ژوئن","ژوئیه","اوت","سپتامبر","اکتبر","نوامبر","دسامبر"}

p.am_pm1 = {}
p.am_pm1['en'] = {"AM","PM"}
p.am_pm1['fa'] = {"ق.ظ.","ب.ظ."}

p.am_pm2 = {}
p.am_pm2['en'] = {"am","pm"}
p.am_pm2['fa'] = {"ق.ظ.","ب.ظ."}

p.nums = {}
p.nums['fa'] = {_0="۰",_1="۱",_2="۲",_3="۳",_4="۴",_5="۵",_6="۶",_7="۷",_8="۸",_9="۹"}

p.timezones = {}
p.timezones['utc'] = {0,0,0,0,"UTC","UTC"}
p.timezones['asia/tehran'] = {12600,16200,80,234,"IRDT","IRST"}

p.gregorian_days_in_months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
p.solar_days_in_months = {31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29};

function p.date_string_to_timestamp(txt)
	txt = tostring(txt)
	if txt ~= nil then
		local xday, xmonth, xyear = txt:match("(%d%d)%s+(%S+)%s+(%d%d%d%d)")
		if xday ~= nil and xmonth ~= nil and xyear ~= nil then
			for i,mname in pairs(p.months1['gregorian']['en']) do
				if xmonth:lower() == mname:lower() then
					xmonth = i
					break
				end
			end
			for i,mname in pairs(p.months2['gregorian']['en']) do
				if tostring(xmonth):lower() == mname:lower() then
					xmonth = i
					break
				end
			end
			txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
		else
			local xday, xmonth, xyear = txt:match("(%d)%s+(%S+)%s+(%d%d%d%d)")
			if xday ~= nil and xmonth ~= nil and xyear ~= nil then
				for i,mname in pairs(p.months1['gregorian']['en']) do
					if xmonth:lower() == mname:lower() then
						xmonth = i
						break
					end
				end
				for i,mname in pairs(p.months2['gregorian']['en']) do
					if tostring(xmonth):lower() == mname:lower() then
						xmonth = i
						break
					end
				end
				txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
			else
				local xmonth, xday, xyear = txt:match("(%S+)%s+(%d%d)%,%s+(%d%d%d%d)")
				if xday ~= nil and xmonth ~= nil and xyear ~= nil then
					for i,mname in pairs(p.months1['gregorian']['en']) do
						if xmonth:lower() == mname:lower() then
							xmonth = i
							break
						end
					end
					for i,mname in pairs(p.months2['gregorian']['en']) do
						if tostring(xmonth):lower() == mname:lower() then
							xmonth = i
							break
						end
					end
					txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
				else
					local xmonth, xday, xyear = txt:match("(%S+)%s+(%d%d)%s+(%d%d%d%d)")
					if xday ~= nil and xmonth ~= nil and xyear ~= nil then
						for i,mname in pairs(p.months1['gregorian']['en']) do
							if xmonth:lower() == mname:lower() then
								xmonth = i
								break
							end
						end
						for i,mname in pairs(p.months2['gregorian']['en']) do
							if tostring(xmonth):lower() == mname:lower() then
								xmonth = i
								break
							end
						end
						txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
					else
						local xmonth, xday, xyear = txt:match("(%S+)%s+(%d)%s+(%d%d%d%d)")
						if xday ~= nil and xmonth ~= nil and xyear ~= nil then
							for i,mname in pairs(p.months1['gregorian']['en']) do
								if xmonth:lower() == mname:lower() then
									xmonth = i
									break
								end
							end
							for i,mname in pairs(p.months2['gregorian']['en']) do
								if tostring(xmonth):lower() == mname:lower() then
									xmonth = i
									break
								end
							end
							txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
						else
							local xyear, xday, xmonth = txt:match("(%d%d%d%d)%s+(%d%d)%s+(%S+)")
							if xday ~= nil and xmonth ~= nil and xyear ~= nil then
								for i,mname in pairs(p.months1['gregorian']['en']) do
									if xmonth:lower() == mname:lower() then
										xmonth = i
										break
									end
								end
								for i,mname in pairs(p.months2['gregorian']['en']) do
									if tostring(xmonth):lower() == mname:lower() then
										xmonth = i
										break
									end
								end
								txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
							else
								local xyear, xday, xmonth = txt:match("(%d%d%d%d)%s+(%d)%s+(%S+)")
								if xday ~= nil and xmonth ~= nil and xyear ~= nil then
									for i,mname in pairs(p.months1['gregorian']['en']) do
										if xmonth:lower() == mname:lower() then
											xmonth = i
											break
										end
									end
									for i,mname in pairs(p.months2['gregorian']['en']) do
										if tostring(xmonth):lower() == mname:lower() then
											xmonth = i
											break
										end
									end
									txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
								else
									local xday, xmonth, xyear = txt:match("(%d%d)(%S+)%s+(%d%d%d%d)")
									if xday ~= nil and xmonth ~= nil and xyear ~= nil then
										for i,mname in pairs(p.months1['gregorian']['en']) do
											if xmonth:lower() == mname:lower() then
												xmonth = i
												break
											end
										end
										for i,mname in pairs(p.months2['gregorian']['en']) do
											if tostring(xmonth):lower() == mname:lower() then
												xmonth = i
												break
											end
										end
										txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
									else
										local xmonth, xday, xyear = txt:match("(%S+)%s+(%d)%,%s+(%d%d%d%d)")
										if xday ~= nil and xmonth ~= nil and xyear ~= nil then
											for i,mname in pairs(p.months1['gregorian']['en']) do
												if xmonth:lower() == mname:lower() then
													xmonth = i
													break
												end
											end
											for i,mname in pairs(p.months2['gregorian']['en']) do
												if tostring(xmonth):lower() == mname:lower() then
													xmonth = i
													break
												end
											end
											txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
										else
											local xyear, xmonth, xday = txt:match("(%d%d%d%d)%-(%d%d)%-(%d%d)")
											if xday ~= nil and xmonth ~= nil and xyear ~= nil then
												txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
											else
												local xday, xmonth, xyear = txt:match("(%d%d)%-(%d%d)%-(%d%d%d%d)")
												if xday ~= nil and xmonth ~= nil and xyear ~= nil then
													txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
												else
													local xday, xmonth, xyear = txt:match("(%d%d)%-(%d)%-(%d%d%d%d)")
													if xday ~= nil and xmonth ~= nil and xyear ~= nil then
														txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
													else
														local xday, xmonth, xyear = txt:match("(%d)%-(%d)%-(%d%d%d%d)")
														if xday ~= nil and xmonth ~= nil and xyear ~= nil then
															txt = os.time({year = xyear, month = xmonth, day = xday, hour = 0, min = 0, sec = 0})
														else
															local xyear, xmonth, xday, xhour, xminute, xsecond = txt:match("(%d%d%d%d)(%d%d)(%d%d)(%d%d)(%d%d)(%d%d)")
															if xday ~= nil and xmonth ~= nil and xyear ~= nil and xhour ~= nil and xminute ~= nil and xsecond ~= nil then
																txt = os.time({year = xyear, month = xmonth, day = xday, hour = xhour, min = xminute, sec = xsecond})
															end
														end
													end
												end
											end
										end
									end
								end
							end
						end
					end
				end
			end
		end
	end
	return txt
end

function p.timestamp(frame)
	local timestamp = frame.args[1]
	if timestamp == nil then
		timestamp = os.time()
	end
	timestamp = p.date_string_to_timestamp(timestamp)
	return timestamp
end

function p.date(frame)
	local jformat = frame.args[1]
	local jtype = frame.args[2]
	local timezone = frame.args[3]
	local jlang = frame.args[4]
	local timestamp = frame.args[5]
	local out = ''
	if jtype == nil then
		jtype = 'gregorian'
	end
	if jtype == 'jalali' then
		jtype = 'solar'
	end
	if timezone == nil then
		timezone = 'UTC'
	end
	if jlang == nil then
		jlang = 'en'
	end
	if timestamp == nil then
		timestamp = os.time()
	end
	timestamp = p.date_string_to_timestamp(timestamp)
	local invalid_parameter = false
	if pcall(math.floor,timestamp) then
		timestamp = math.floor(timestamp)
	else
		invalid_parameter = true
	end
	if invalid_parameter == true then
		out = "[[رده:صفحه‌های دارای پارامتر نادرست در الگوی تاریخ]] پارامتر ورودی تابع date از [[Module:Date]] اشتباه است."
	else
		local abbr = timezone
		local offset = ""
		local diff_greenwich = ""
		local diff_greenwich_colon = ""
		local jday_of_year = math.floor(os.date('%j',timestamp))
		local tz_data = p.fix_timezone(timestamp,jday_of_year,timezone)
		timestamp = tz_data[1]
		abbr = tz_data[2]
		offset = tz_data[3]
		diff_greenwich = tz_data[4]
		diff_greenwich_colon = tz_data[5]
		local jdate = mw.text.split(os.date('%Y %m %d %w %r %j',timestamp)," ")
		local jyear = math.floor(jdate[1])
		local jmonth = math.floor(jdate[2])
		local jday = math.floor(jdate[3])
		local jweekday = jdate[4]
		local jtime = mw.text.split(jdate[5],":")
		local j_am_pm = jdate[6]
		local jday_of_year = math.floor(jdate[7])
		local jhour = math.floor(jtime[1])
		local jhour2 = jhour
		if j_am_pm == "PM" then
			jhour2 = jhour2 + 12
		elseif jhour2 == 12 then
			jhour2 = 0
		end
		local jmin = jtime[2]
		local jsec = jtime[3]
		if jtype == 'solar' then
			jdate = p.gregorian_to_solar(jyear,jmonth,jday)
			jyear = jdate[1]
			jmonth = jdate[2]
			jday = jdate[3]
		end
		local ignore = false
		for i = 1, string.len(jformat) do
			local c = string.sub(jformat, i, i)
			if ignore == true then
				out = out .. c
				ignore = false
			elseif c == "Y" then
				out = out .. jyear
			elseif c == "F" then
				out = out .. p.month_to_name1(jmonth,jtype,jlang)
			elseif c == "j" then
				out = out .. math.floor(jday)
			elseif c == "l" then
				out = out .. p.weekday_to_name1(jweekday,jlang)
			elseif c == "g" then
				out = out .. math.floor(jhour)
			elseif c == "i" then
				out = out .. p.padzero(jmin)
			elseif c == "s" then
				out = out .. p.padzero(jsec)
			elseif c == "A" then
				out = out .. p.localize_am_pm1(j_am_pm,jlang)
			elseif c == "a" then
				out = out .. p.localize_am_pm2(j_am_pm,jlang)
			elseif c == "z" then
				out = out .. jday_of_year
			elseif c == "N" then
				out = out .. jweekday
			elseif c == "w" then
				out = out .. jweekday - 1
			elseif c == "d" then
				out = out .. p.padzero(jday)
			elseif c == "n" then
				out = out .. math.floor(jmonth)
			elseif c == "m" then
				out = out .. p.padzero(jmonth)
			elseif c == "h" then
				out = out .. p.padzero(jhour)
			elseif c == "G" then
				out = out .. math.floor(jhour2)
			elseif c == "H" then
				out = out .. p.padzero(jhour2)
			elseif c == "T" then
				out = out .. abbr
			elseif c == "Z" then
				out = out .. offset
			elseif c == "O" then
				out = out .. diff_greenwich
			elseif c == "P" then
				out = out .. diff_greenwich_colon
			elseif c == "\\" then
				ignore = true
			else
				out = out .. c
			end
		end
		out = p.localize_nums(out,jlang)
	end
	return out
end

function p.time()
	return os.time()
end

function p.padzero(num)
	num = tostring(num)
	if string.len(num) == 1 then
		num = "0" .. num
	end
	return num
end

function p.fix_timezone(timestamp,day_of_year,timezone)
	local abbr = timezone
	local offset = 0
	local diff_greenwich = "+0000"
	local diff_greenwich_colon = "+00:00"
	if p.timezones[mw.ustring.lower(timezone)] ~= nil then
		local tz = p.timezones[mw.ustring.lower(timezone)]
		if day_of_year >= tz[3] and day_of_year <= tz[4] then
			timestamp = timestamp + tz[2]
			abbr = tz[5]
			offset = tz[2]
			diff_greenwich_data = p.make_diff_greenwich(tz[2])
			diff_greenwich = diff_greenwich_data[1]
			diff_greenwich_colon = diff_greenwich_data[2]
		else
			timestamp = timestamp + tz[1]
			abbr = tz[6]
			offset = tz[2]
			diff_greenwich_data = p.make_diff_greenwich(tz[1])
			diff_greenwich = diff_greenwich_data[1]
			diff_greenwich_colon = diff_greenwich_data[2]
		end
	end
	return {timestamp,abbr,offset,diff_greenwich,diff_greenwich_colon}
end

function p.make_diff_greenwich(diff_in_seconds)
	local diff_greenwich = ""
	local diff_greenwich_colon = ""
	if diff_in_seconds >= 0 then
		diff_greenwich = diff_greenwich .. "+"
		diff_greenwich_colon = diff_greenwich_colon .. "+"
	else
		diff_greenwich = diff_greenwich .. "-"
		diff_greenwich_colon = diff_greenwich_colon .. "-"
		diff_in_seconds = diff_in_seconds + (diff_in_seconds * 2)
	end
	local hour = p.padzero(math.floor(diff_in_seconds/3600))
	extra_minutes = p.padzero((diff_in_seconds - (math.floor(diff_in_seconds/3600) * 3600)) / 60)
	diff_greenwich = diff_greenwich .. hour .. extra_minutes
	diff_greenwich_colon = diff_greenwich_colon .. hour .. ":" .. extra_minutes
	return {diff_greenwich,diff_greenwich_colon}
end

function p.localize_nums(str,lang)
	local out = ''
	for i = 1, string.len(str) do
		local c = string.sub(str, i, i)
		if p.nums[lang] ~= nil and p.nums[lang]["_"..c] ~= nil then
			out = out .. p.nums[lang]["_"..c]
		else
			out = out .. c
		end
	end
	return out
end

function p.localize_am_pm1(str,lang)
	if str == "AM" then
		return p.am_pm1[lang][1]
	else
		return p.am_pm1[lang][2]
	end
end

function p.localize_am_pm2(str,lang)
	if str == "AM" then
		return p.am_pm2[lang][1]
	else
		return p.am_pm2[lang][2]
	end
end

function p.weekday_to_name1(day,lang)
	return p.weekdays1[lang][math.floor(day)+1]
end

function p.month_to_name1(month,jtype,lang)
	return p.months1[jtype][lang][math.floor(month)]
end

function p.gregorian_to_solar(g_y,g_m,g_d,jmod)
	if jmod == nil then 
		jmod = ''
	end
	d_4 = g_y % 4
	g_a = {0,0,31,59,90,120,151,181,212,243,273,304,334}
	doy_g = g_a[math.floor(g_m)+1] + g_d
	if d_4 == 0 and g_m > 2 then
		doy_g = doy_g + 1
	end
	d_33 = math.floor(((g_y-16)%132)*0.0305)
	if d_33==3 or d_33 < (d_4 - 1) or d_4 == 0 then
		a = 286
	else
		a = 287
	end
	if (d_33 == 1 or d_33 == 2) and (d_33 == d_4 or d_4 == 1) then
		b = 78
	elseif (d_33==3 and d_4==0) then
		b = 80
	else
		b = 79
	end
	if math.floor((g_y-10)/63) == 30 then
		a = a - 1
		b = b + 1
	end
	if doy_g > b then
		jy= g_y - 621
		doy_j = doy_g - b
	else
		jy = g_y - 622
		doy_j = doy_g + a
	end
	if doy_j < 187 then
		jm = math.floor((doy_j-1)/31)
		jd = doy_j - (31 * jm)
		jm = jm + 1
	else
		jm = math.floor((doy_j-187)/30)
		jd = doy_j - 186 - (jm * 30)
		jm = jm + 7
	end
	if jmod == '' then
		return {jy,jm,jd}
	else
		return tostring(jy) .. tostring(mod) .. tostring(jm) .. tostring(mod) .. tostring(jd)
	end
end

function p.div(a, b)
	return math.floor(a / b);
end

function p.remainder(a, b)
	return a - math.floor(a / b) * b;
end

function p.solar_to_gregorian(j)
	local leap = 0
	local i = 0
	local jy = j[1] - 979;
	local jm = j[2] - 1;
	local jd = j[3] - 1;
	local j_day_no = 365 * jy + p.div(jy, 33) * 8 + p.div((p.remainder(jy, 33) + 3), 4)
	local i = 0
	while true do
		if i >= jm then
			break
		end
		j_day_no = j_day_no + p.solar_days_in_months[i+1]
		i = i + 1
	end
	j_day_no = j_day_no + jd
	local g_day_no = j_day_no + 79
	local gy = 1600 + 400 * p.div(g_day_no, 146097)
	g_day_no = p.remainder(g_day_no, 146097)
	leap = 1
	if g_day_no >= 36525 then
		g_day_no = g_day_no - 1;
		gy = gy + (100 * p.div(g_day_no, 36524))
		g_day_no = p.remainder(g_day_no, 36524)
		if g_day_no >= 365 then
			g_day_no = g_day_no + 1
		else
			leap = 0
		end
	end
	gy = gy + (4 * p.div(g_day_no, 1461))
	g_day_no = p.remainder(g_day_no, 1461)
	if g_day_no >= 366 then
		leap = 0
		g_day_no = g_day_no - 1
		gy = gy + p.div(g_day_no, 365)
		g_day_no = p.remainder(g_day_no, 365)
	end
	local i = 0
	local extra = 0
	while true do
		extra = 0
		if i == 1 and leap == 1 then
			extra = 1
		end
		if g_day_no < p.gregorian_days_in_months[i+1] - extra then
			break
		end
		g_day_no = g_day_no - p.gregorian_days_in_months[i+1] - extra
		i = i + 1
	end
	local gm = i + 1
	local gd = g_day_no + 1
	return {gy, gm, gd}
end


return p