मोड्युल:स्रोत/पहुँच मिति
स्वरूप
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