सामग्रीमा जानुहोस्

मोड्युल:स्रोत/पहुँच मिति

विकिपिडिया, एक स्वतन्त्र विश्वकोशबाट
local p = {}

--[[--------------------------< F O R W A R D   D E C L A R A T I O N S >--------------------------------------
]]

local is_set, in_array;															-- imported functions from selected मोड्युल:स्रोत/उपयोगिता
local cfg;																		-- table of tables imported from selected मोड्युल:स्रोत/रूपरेखा

-- अङ्ग्रेजी अङ्क छ कि छैन जाँच गर्ने (यदि छ भने अमान्य मान्नका लागि)
local function has_english_digits (str)
	if not str then return false end
	return str:match('[0-9]') ~= nil
end

-- अङ्क परिवर्तनका लागि सहयोगी फङ्क्शन (नेपाली अङ्क -> अङ्ग्रेजी अङ्क - आन्तरिक हिसाबका लागि मात्र)
local function to_en_digits (str)
	if not str then return nil end
	local devanagari_digits = {['०']='0', ['१']='1', ['२']='2', ['३']='3', ['४']='4', ['५']='5', ['६']='6', ['७']='7', ['८']='8', ['९']='9'}
	return (str:gsub('[०-९]', devanagari_digits))
end

--[[--------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
]]

local function is_valid_accessdate (accessdate)
	if has_english_digits(accessdate) then return false end                      -- अङ्ग्रेजी अङ्क भए अस्वीकार गर्ने
	
	local lang = mw.getContentLanguage();
	local good1, good2;
	local access_ts, tomorrow_ts;												
	
	local clean_accessdate = to_en_digits(accessdate);
		
	good1, access_ts = pcall( lang.formatDate, lang, 'U', clean_accessdate );			
	good2, tomorrow_ts = pcall( lang.formatDate, lang, 'U', 'today + 2 days' );	
	
	if good1 and good2 then														
		access_ts = tonumber (access_ts) or lang:parseFormattedNumber (access_ts);			
		tomorrow_ts = tonumber (tomorrow_ts) or lang:parseFormattedNumber (tomorrow_ts);
	else
		return false;															
	end

	if 979516800 <= access_ts and access_ts < tomorrow_ts then					
		return true;
	else
		return false;															
	end
end


--[[--------------------------< G E T _ M O N T H _ N U M B E R >----------------------------------------------
]]

local function get_month_number (month)
	if not cfg or not cfg.date_names then
		-- नेपाली महिनाहरू
		local months = {
			['वैशाख']=1, ['बैशाख']=1, ['जेठ']=2, ['ज्येष्ठ']=2, ['असार']=3, ['आषाढ']=3,
			['साउन']=4, ['श्रावण']=4, ['भदौ']=5, ['भाद्र']=5, ['असोज']=6, ['आश्विन']=6,
			['कात्तिक']=7, ['कार्तिक']=7, ['मंसिर']=8, ['मङ्सीर']=8, ['पुस']=9, ['पौष']=9,
			['माघ']=10, ['फागुन']=11, ['फाल्गुन']=11, ['चैत']=12, ['चैत्र']=12
		}
		return months[month] or 0
	end
	return cfg.date_names['local'].long[month] or cfg.date_names['local'].short[month] or 0;																					
end


--[[--------------------------< I S _ V A L I D _ E M B A R G O _ D A T E >------------------------------------
]]

local function is_valid_embargo_date (v)
	if has_english_digits(v) then return false, '9999' end                     -- अङ्ग्रेजी अङ्क भए अस्वीकार गर्ने
	local clean_v = to_en_digits(v)
	if clean_v:match ('^%d%d%d%d%-%d%d%-%d%d$') or									
		v:match ('^[०-९][०-९]?%s+%D-+%s+[०-९][०-९][०-९][०-९]$') then							
			return true, v;
	end
	return false, '9999';														
end


--[[--------------------------< G E T _ S E A S O N _ N U M B E R >--------------------------------------------
]]

local function get_season_number (season)
	if not cfg or not cfg.date_names then return 0 end
	return cfg.date_names['local'].season[season] or 0;																	
end

--[[--------------------------< I S _ P R O P E R _ N A M E >--------------------------------------------------
]]

local function is_proper_name (name)
	if not cfg or not cfg.date_names then return 0 end
	return cfg.date_names['local'].named[name] or 0;																	
end

--[[--------------------------< I S _ V A L I D _ M O N T H _ O R _ S E A S O N >------------------------------
]]

local function is_valid_month_or_season (month_season)
	if 0 == get_month_number (month_season) then		
		if 0 == get_season_number (month_season) then	
			return false;								
		end
	end
	return true;
end

--[[--------------------------< I S _ V A L I D _ Y E A R >----------------------------------------------------
]]

local year_limit;
local function is_valid_year(year)
	year = tonumber(to_en_digits(year));
	if not year then return false end
	if not is_set(year_limit) then
		year_limit = tonumber(os.date("%Y")) + 57 + 1;			-- वि.सं. को लागि भविष्यको वर्ष सीमा
	end
	return year <= year_limit;				
end

--[[--------------------------< I S _ V A L I D _ D A T E >----------------------------------------------------
]]

local function is_valid_date (year, month, day)
	local days_in_month = {32, 32, 32, 32, 32, 31, 30, 30, 30, 30, 30, 30}; -- नेपाली वि.सं. महिनाका दिनहरू
	local month_length;
	
	year = tonumber(to_en_digits(year));
	month = tonumber(to_en_digits(month));
	day = tonumber(to_en_digits(day));

	if not year or not month or not day then return false end
	if not is_valid_year(year) then return false end
	if month < 1 or month > 12 then return false end
	
	month_length = days_in_month[month];

	if day < 1 or day > month_length then
		return false;
	end
	return true;
end


--[[--------------------------< M A K E _ C O I N S _ D A T E >------------------------------------------------
]]

local function make_COinS_date (input, tCOinS_date)
	local date;																	
	local date2 = '';															
	
	local year = tonumber(to_en_digits(input.year));											
	local month = tonumber(to_en_digits(input.month));										
	local day = tonumber(to_en_digits(input.day));
	
	if 0 ~= day then
		date = string.format ('%s-%.2d-%.2d', year, month, day);	
	elseif 0 ~= month then
		date = string.format ('%s-%.2d', year, month);	
	else
		date = string.format ('%s', year);								
	end

	if 0 ~= input.year2 then
		local year2 = tonumber(to_en_digits(input.year2));
		local month2 = tonumber(to_en_digits(input.month2));
		local day2 = tonumber(to_en_digits(input.day2));
		if 0 ~= day2 then
			date2 = string.format ('/%s-%.2d-%.2d', year2, month2, day2);		
		elseif 0 ~= month2 then
			date2 = string.format ('/%s-%.2d', year2, month2);	
		else
			date2 = string.format ('/%s', year2);							
		end
	end
	
	tCOinS_date.rftdate = date .. date2;										
	return;
end


--[[--------------------------< C H E C K _ D A T E >----------------------------------------------------------
]]

local function check_date (date_string, tCOinS_date, test_accessdate)
	-- यदि कुनै पनि अङ्ग्रेजी अङ्क (0-9) छ भने सिधै अमान्य गर्ने
	if has_english_digits(date_string) then
		return false;
	end

	local year;			
	local year2=0;		
	local month=0;
	local month2=0;		
	local day=0;
	local day2=0;		
	local anchor_year;

	if mw.ustring.match(date_string, "^[०-९][०-९]? +%D-+ +[०-९][०-९][०-९][०-९]%a?$") then			-- २५ साउन २०८३ (केवल देवनागरी अङ्क)
		local raw_day, raw_month, raw_year = mw.ustring.match(date_string, "([०-९][०-९]?) +(%D-) +(([०-९][०-९][०-९][०-९])%a?)");
		day = to_en_digits(raw_day);
		year = to_en_digits(raw_year);
		anchor_year = raw_year;
		month = get_month_number (raw_month);
		if 0 == month then return false; end												

	elseif mw.ustring.match(date_string, "^%D-+ +[०-९][०-९]?, +[०-९][०-९][०-९][०-९]%a?$") then						-- साउन २५, २०८३
		local raw_month, raw_day, raw_year = mw.ustring.match(date_string, "(%D-) +([०-९][०-९]?),%s*(([०-९][०-९][०-९][०-९])%a?)");
		day = to_en_digits(raw_day);
		year = to_en_digits(raw_year);
		anchor_year = raw_year;
		month = get_month_number (raw_month);
		if 0 == month then return false; end												
				
	elseif mw.ustring.match(date_string, "^%D-+ +[०-९][०-९]?%s*[%-–]%s*[०-९][०-९]?, +[०-९][०-९][०-९][०-९]%a?$") then	-- साउन २५–२८, २०८३
		local raw_month, raw_day, raw_day2, raw_year = mw.ustring.match(date_string, "(%D-) +([०-९][०-९]?)%s*[%-–]%s*([०-९][०-९]?), +(([०-९][०-९][०-९][०-९])%a?)");
		day = to_en_digits(raw_day); 
		day2 = to_en_digits(raw_day2); 
		year = to_en_digits(raw_year);
		if tonumber(day) >= tonumber(day2) then return false; end							
		month = get_month_number (raw_month);
		if 0 == month then return false; end												
		month2 = month;																		
		year2 = year;

	elseif mw.ustring.match(date_string, "^%D-+ +[०-९][०-९][०-९][०-९]%a?$") then								-- साउन २०८३ (महिना र वर्ष)
		local raw_month, raw_anchor, raw_year = mw.ustring.match(date_string, "(%D-)%s*(([०-९][०-९][०-९][०-९])%a?)");
		year = to_en_digits(raw_year);
		anchor_year = raw_anchor;
		if not is_valid_year(year) then return false; end
		if not is_valid_month_or_season (raw_month) and 0 == is_proper_name (raw_month) then return false; end
		month = get_month_number(raw_month);

	elseif mw.ustring.match(date_string, "^[०-९][०-९][०-९][०-९]%a?$") then									-- वर्ष मात्र (२०८३)
		anchor_year = date_string;
		year = to_en_digits(date_string:match("([०-९][०-९][०-९][०-९])"));
		if false == is_valid_year(year) then
			return false;
		end

	else
		return false;															
	end

	if test_accessdate then														
		if 0 ~= tonumber(year or 0) and 0 ~= tonumber(month or 0) and 0 ~= tonumber(day or 0) then	
				if not is_valid_accessdate (date_string) then	
					return false;												
				end
		else
			return false;														
		end
	end

	local result = true;															
	if 0 ~= tonumber(year or 0) and 0 ~= tonumber(month or 0) and 0 ~= tonumber(day or 0) then		
		result = is_valid_date(year, month, day);
	end
	
	if false == result then return false; end

	if nil ~= tCOinS_date then													
		make_COinS_date ({year=year, month=month, day=day, year2=year2, month2=month2, day2=day2}, tCOinS_date);	
	end
	
	return true, anchor_year;													
end	


--[[--------------------------< D A T E S >--------------------------------------------------------------------
]]

local function dates(date_parameters_list, tCOinS_date)
	local anchor_year;		
	local COinS_date;		
	local embargo_date;															
	local error_message = "";
	local good_date = false;
	
	for k, v in pairs(date_parameters_list) do									
		if is_set(v) then														
			if 'मिति' == k or 'date' == k then												
				if v:match("^n%.d%.%a?$") or v:match("^nd%a?$") then									
					anchor_year = v;												
					good_date = true;
				else
					good_date, anchor_year = check_date (v, tCOinS_date);			
				end
			elseif 'पहुँचमिति' == k or 'accessdate' == k then
				good_date = check_date (v, nil, true);								
			elseif 'सङ्ग्रहमिति' == k or 'archivedate' == k then
				good_date = check_date (v);											
			elseif 'एमबार्गो' == k or 'embargo' == k then
				good_date, embargo_date = is_valid_embargo_date (v);				
				if true == good_date then
					good_date = check_date (embargo_date);							
				end
			elseif 'वर्ष' == k or 'year' == k then
				good_date, anchor_year = check_date (v);							
			else
				good_date = check_date (v);											
			end

			if not good_date then
				if is_set (error_message) then
					error_message = error_message .. '। ';
				end
				local msg_fmt = (cfg and cfg.messages and cfg.messages['bad_date']) or "अमान्य `%s` मिति";
				error_message = error_message .. string.format (msg_fmt, k);
			end
		end
	end

	return error_message, anchor_year, embargo_date;
end


--[[--------------------------< Y E A R _ D A T E _ C H E C K >------------------------------------------------
]]

local function year_date_check (date_string, year_string)
	local year_in_date;
	local disambig_in_date;
	local year_in_year;
	local disambig_in_year;

	if not is_set (date_string) or not is_set (year_string) then
		return nil;																
	end

	if has_english_digits(date_string) or has_english_digits(year_string) then
		return string.format (cfg.messages['date_year_mismatch'], 'मिति', 'वर्ष');
	end

	local clean_date = to_en_digits(date_string);
	local clean_year = to_en_digits(year_string);

	year_in_date, disambig_in_date = clean_date:match ("(%d%d%d%d)(%a?)");
	year_in_year, disambig_in_year = clean_year:match ("(%d%d%d%d)(%a?)");

	if not year_in_date or not year_in_year then
		return nil;																
	end

	if year_in_date == year_in_year then
		if is_set (disambig_in_date) or is_set (disambig_in_year) then
			if disambig_in_date == disambig_in_year then
				return string.format (cfg.messages['redundant_parameters'], 'मिति' .. ' र ' .. 'वर्ष');
			else
				return string.format (cfg.messages['date_year_mismatch'], 'मिति', 'वर्ष');
			end
		else
			return string.format (cfg.messages['redundant_parameters'], 'मिति' .. ' र ' .. 'वर्ष');
		end
	else
		return string.format (cfg.messages['date_year_mismatch'], 'मिति', 'वर्ष');
	end
end


--[[--------------------------< E X P O R T E D   F U N C T I O N S >------------------------------------------
]]

p.dates = dates;
p.year_date_check = year_date_check;

return p