Sửa đổi Mô đun:Citation/Date validation
Chú ý: Bạn chưa đăng nhập và địa chỉ IP của bạn sẽ hiển thị công khai khi lưu các sửa đổi.
Bạn có thể tham gia như người biên soạn chuyên nghiệp và lâu dài ở Bách khoa Toàn thư Việt Nam, bằng cách đăng ký và đăng nhập - IP của bạn sẽ không bị công khai và có thêm nhiều lợi ích khác.
Các sửa đổi có thể được lùi lại. Xin hãy kiểm tra phần so sánh bên dưới để xác nhận lại những gì bạn muốn làm, sau đó lưu thay đổi ở dưới để hoàn tất việc lùi lại sửa đổi.
Bản hiện tại | Nội dung bạn nhập | ||
Dòng 4: | Dòng 4: | ||
local is_set, in_array; -- imported functions from selected Module:Citation/CS1/Utilities | local is_set, in_array; -- imported functions from selected Module:Citation/CS1/Utilities | ||
− | local cfg; -- table of tables imported from selected Module:Citation/Configuration | + | local cfg; -- table of tables imported from selected Module:Citation/CS1/Configuration |
Dòng 20: | Dòng 20: | ||
returns true if: | returns true if: | ||
− | + | Wikipedia start date <= accessdate < today + 2 days | |
− | + | Wikipedia start date is 2001-01-15T00:00:00 UTC which is 979516800 seconds after 1970-01-01T00:00:00 UTC (the start of Unix time) | |
accessdate is the date provided in |accessdate= at time 00:00:00 UTC | accessdate is the date provided in |accessdate= at time 00:00:00 UTC | ||
today is the current date at time 00:00:00 UTC plus 48 hours | today is the current date at time 00:00:00 UTC plus 48 hours | ||
− | if today is | + | if today is 2015-01-01T00:00:00 then |
− | adding 24 hours gives | + | adding 24 hours gives 2015-01-02T00:00:00 – one second more than today |
− | adding 24 hours gives | + | adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow |
This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser | This function does not work if it is fed month names for languages other than English. Wikimedia #time: parser | ||
Dòng 50: | Dòng 50: | ||
end | end | ||
− | + | if 979516800 <= access_ts and access_ts < tomorrow_ts then -- Wikipedia start date <= accessdate < tomorrow's date | |
− | |||
return true; | return true; | ||
else | else | ||
Dòng 69: | Dòng 68: | ||
local function is_valid_embargo_date (v) | local function is_valid_embargo_date (v) | ||
− | if v:match ('^%d%d%d%d%-%d%d%-%d%d$') or -- ymd | + | if v:match ('^%d%d%d%d%-%d%d%-%d%d$') or -- ymd |
− | v:match ('^%d%d?%s+%a+%s+ | + | v:match ('^%d%d?%s+%a+%s+%d%d%d%d$') or -- dmy |
− | + | v:match ('^%a+%s+%d%d?%s*,%s*%d%d%d%d$') then -- mdy | |
− | v:match ('^%a+%s+%d%d?%s*,%s*%d%d%d%d$') | ||
− | |||
− | |||
− | |||
return true, v; | return true, v; | ||
end | end | ||
− | return false, '9999'; | + | return false, '9999'; -- if here not good date so return false and set embargo date to long time in future |
end | end | ||
+ | |||
--[[--------------------------< G E T _ M O N T H _ N U M B E R >---------------------------------------------- | --[[--------------------------< G E T _ M O N T H _ N U M B E R >---------------------------------------------- | ||
Dòng 91: | Dòng 87: | ||
return cfg.date_names['local'].long[month] or cfg.date_names['local'].short[month] or -- look for local names first | return cfg.date_names['local'].long[month] or cfg.date_names['local'].short[month] or -- look for local names first | ||
cfg.date_names['en'].long[month] or cfg.date_names['en'].short[month] or -- failing that, look for English names | cfg.date_names['en'].long[month] or cfg.date_names['en'].short[month] or -- failing that, look for English names | ||
− | 0; | + | 0; -- not a recognized month name |
end | end | ||
Dòng 119: | Dòng 115: | ||
local function get_season_number (season, param) | local function get_season_number (season, param) | ||
if 'date' ~= param then | if 'date' ~= param then | ||
− | return 0; | + | return 0; -- season dates only supported by |date= |
end | end | ||
return cfg.date_names['local'].season[season] or -- look for local names first | return cfg.date_names['local'].season[season] or -- look for local names first | ||
cfg.date_names['en'].season[season] or -- failing that, look for English names | cfg.date_names['en'].season[season] or -- failing that, look for English names | ||
− | 0; | + | 0; -- not a recognized season name |
end | end | ||
Dòng 147: | Dòng 143: | ||
local function get_quarter_number (quarter, param) | local function get_quarter_number (quarter, param) | ||
if 'date' ~= param then | if 'date' ~= param then | ||
− | return 0; | + | return 0; -- quarter dates only supported by |date= |
end | end | ||
quarter = mw.ustring.gsub (quarter, ' +', ' '); -- special case replace multiple space chars with a single space char | quarter = mw.ustring.gsub (quarter, ' +', ' '); -- special case replace multiple space chars with a single space char | ||
return cfg.date_names['local'].quarter[quarter] or -- look for local names first | return cfg.date_names['local'].quarter[quarter] or -- look for local names first | ||
cfg.date_names['en'].quarter[quarter] or -- failing that, look for English names | cfg.date_names['en'].quarter[quarter] or -- failing that, look for English names | ||
− | 0; | + | 0; -- not a recognized quarter name |
end | end | ||
Dòng 166: | Dòng 162: | ||
local function get_proper_name_number (name, param) | local function get_proper_name_number (name, param) | ||
if 'date' ~= param then | if 'date' ~= param then | ||
− | return 0; | + | return 0; -- proper-name dates only supported by |date= |
end | end | ||
return cfg.date_names['local'].named[name] or -- look for local names dates first | return cfg.date_names['local'].named[name] or -- look for local names dates first | ||
− | cfg.date_names['en'].named[name] or | + | cfg.date_names['en'].named[name] or -- failing that, look for English names |
− | 0; | + | 0; -- not a recognized named date |
end | end | ||
Dòng 185: | Dòng 181: | ||
local funcs = {get_month_number, get_season_number, get_quarter_number, get_proper_name_number}; -- list of functions to execute in order | local funcs = {get_month_number, get_season_number, get_quarter_number, get_proper_name_number}; -- list of functions to execute in order | ||
− | for _, func in ipairs (funcs) do | + | for _, func in ipairs (funcs) do -- spin through the function list |
− | num = func (element, param); | + | num = func (element, param); -- call the function and get the returned number |
− | if 0 ~= num then | + | if 0 ~= num then -- non-zero when valid month season quarter |
− | return num; | + | return num; -- return that number |
end | end | ||
end | end | ||
− | return nil; | + | return nil; -- not valid |
end | end | ||
Dòng 204: | Dòng 200: | ||
local function is_valid_year (year) | local function is_valid_year (year) | ||
if not is_set(year_limit) then | if not is_set(year_limit) then | ||
− | year_limit = tonumber(os.date("%Y"))+1; | + | year_limit = tonumber(os.date("%Y"))+1; -- global variable so we only have to fetch it once |
end | end | ||
Dòng 226: | Dòng 222: | ||
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | ||
local month_length; | local month_length; | ||
− | if not is_valid_year(year) then | + | if not is_valid_year(year) then -- no farther into the future than next year |
return false; | return false; | ||
end | end | ||
− | month = tonumber(month); | + | month = tonumber(month); -- required for YYYY-MM-DD dates |
− | if (2==month) then | + | if (2==month) then -- if February |
− | month_length = 28; | + | month_length = 28; -- then 28 days unless |
− | if 1582 > tonumber(year) then | + | if 1582 > tonumber(year) then -- Julian calendar |
if 0==(year%4) then -- is a leap year? | if 0==(year%4) then -- is a leap year? | ||
month_length = 29; -- if leap year then 29 days in February | month_length = 29; -- if leap year then 29 days in February | ||
Dòng 424: | Dòng 420: | ||
local patterns = { | local patterns = { | ||
− | + | -- year-initial numerical year-month-day | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
['ymd'] = {'^(%d%d%d%d)%-(%d%d)%-(%d%d)$', 'y', 'm', 'd'}, | ['ymd'] = {'^(%d%d%d%d)%-(%d%d)%-(%d%d)$', 'y', 'm', 'd'}, | ||
− | + | -- month-initial: month day, year | |
['Mdy'] = {'^(%D-) +([1-9]%d?), +((%d%d%d%d?)%a?)$', 'm', 'd', 'a', 'y'}, | ['Mdy'] = {'^(%D-) +([1-9]%d?), +((%d%d%d%d?)%a?)$', 'm', 'd', 'a', 'y'}, | ||
− | + | -- month-initial day range: month day–day, year; days are separated by endash | |
['Md-dy'] = {'^(%D-) +([1-9]%d?)[%-–]([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'd2', 'a', 'y'}, | ['Md-dy'] = {'^(%D-) +([1-9]%d?)[%-–]([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'd2', 'a', 'y'}, | ||
− | + | -- day-initial: day month year | |
['dMy'] = {'^([1-9]%d?) +(%D-) +((%d%d%d%d?)%a?)$', 'd', 'm', 'a', 'y'}, | ['dMy'] = {'^([1-9]%d?) +(%D-) +((%d%d%d%d?)%a?)$', 'd', 'm', 'a', 'y'}, | ||
− | + | -- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed; not supported at en.wiki | |
+ | -- ['yMd'] = {'^((%d%d%d%d?)%a?) +(%D-) +(%d%d?)$', 'a', 'y', 'm', 'd'}, | ||
+ | -- day-range-initial: day–day month year; days are separated by endash | ||
['d-dMy'] = {'^([1-9]%d?)[%-–]([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'd2', 'm', 'a', 'y'}, | ['d-dMy'] = {'^([1-9]%d?)[%-–]([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'd2', 'm', 'a', 'y'}, | ||
− | + | -- day initial month-day-range: day month - day month year; uses spaced endash | |
['dM-dMy'] = {'^([1-9]%d?) +(%D-) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'd2', 'm2', 'a', 'y'}, | ['dM-dMy'] = {'^([1-9]%d?) +(%D-) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'd2', 'm2', 'a', 'y'}, | ||
− | + | -- month initial month-day-range: month day – month day, year; uses spaced endash | |
['Md-Mdy'] = {'^(%D-) +([1-9]%d?) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$','m', 'd', 'm2', 'd2', 'a', 'y'}, | ['Md-Mdy'] = {'^(%D-) +([1-9]%d?) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$','m', 'd', 'm2', 'd2', 'a', 'y'}, | ||
− | + | -- day initial month-day-year-range: day month year - day month year; uses spaced endash | |
['dMy-dMy'] = {'^([1-9]%d?) +(%D-) +(%d%d%d%d) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'y', 'd2', 'm2', 'a', 'y2'}, | ['dMy-dMy'] = {'^([1-9]%d?) +(%D-) +(%d%d%d%d) +[%-–] +([1-9]%d?) +(%D-) +((%d%d%d%d)%a?)$', 'd', 'm', 'y', 'd2', 'm2', 'a', 'y2'}, | ||
− | + | -- month initial month-day-year-range: month day, year – month day, year; uses spaced endash | |
['Mdy-Mdy'] = {'^(%D-) +([1-9]%d?), +(%d%d%d%d) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'y', 'm2', 'd2', 'a', 'y2'}, | ['Mdy-Mdy'] = {'^(%D-) +([1-9]%d?), +(%d%d%d%d) +[%-–] +(%D-) +([1-9]%d?), +((%d%d%d%d)%a?)$', 'm', 'd', 'y', 'm2', 'd2', 'a', 'y2'}, | ||
− | + | -- these date formats cannot be converted, per se, but month name can be rendered short or long | |
− | + | -- month/season year - month/season year; separated by spaced endash | |
['My-My'] = {'^(%D-) +(%d%d%d%d) +[%-–] +(%D-) +((%d%d%d%d)%a?)$', 'm', 'y', 'm2', 'a', 'y2'}, | ['My-My'] = {'^(%D-) +(%d%d%d%d) +[%-–] +(%D-) +((%d%d%d%d)%a?)$', 'm', 'y', 'm2', 'a', 'y2'}, | ||
− | + | -- month/season range year; months separated by endash | |
['M-My'] = {'^(%D-)[%-–](%D-) +((%d%d%d%d)%a?)$', 'm', 'm2', 'a', 'y'}, | ['M-My'] = {'^(%D-)[%-–](%D-) +((%d%d%d%d)%a?)$', 'm', 'm2', 'a', 'y'}, | ||
− | + | -- month/season year or proper-name year; quarter year when First Quarter YYYY etc | |
− | ['My'] = {'^([^%d–]-) +((%d%d%d%d)%a?)$', 'm', 'a', 'y'}, | + | ['My'] = {'^([^%d–]-) +((%d%d%d%d)%a?)$', 'm', 'a', 'y'}, -- this way because endash is a member of %D; %D- will match January–March 2019 when it shouldn't |
− | ['Sy4-y2'] = {'^(%D-) +((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash | + | -- these date formats cannot be converted |
− | ['Sy-y'] = {'^(%D-) +(%d%d%d%d)[%-–]((%d%d%d%d)%a?)$'}, -- special case Winter/Summer year-year; year separated with unspaced endash | + | -- ['Q,y'] = {'^(Q%a* +[1-4]), +((%d%d%d%d)%a?)$'}, -- Quarter n, yyyy |
− | ['y-y'] = {'^(%d%d%d%d?)[%-–]((%d%d%d%d?)%a?)$'}, -- year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999 | + | |
− | ['y4-y2'] = {'^((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, | + | ['Sy4-y2'] = {'^(%D-) +((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- special case Winter/Summer year-year (YYYY-YY); year separated with unspaced endash |
− | ['y'] = {'^((%d%d%d%d?)%a?)$'}, | + | ['Sy-y'] = {'^(%D-) +(%d%d%d%d)[%-–]((%d%d%d%d)%a?)$'}, -- special case Winter/Summer year-year; year separated with unspaced endash |
+ | ['y-y'] = {'^(%d%d%d%d?)[%-–]((%d%d%d%d?)%a?)$'}, -- year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999 | ||
+ | ['y4-y2'] = {'^((%d%d)%d%d)[%-–]((%d%d)%a?)$'}, -- year range: YYYY–YY; separated by unspaced endash | ||
+ | ['y'] = {'^((%d%d%d%d?)%a?)$'}, -- year; here accept either YYY or YYYY | ||
} | } | ||
Dòng 503: | Dòng 496: | ||
if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or 0 == tonumber(day) then return false; end -- month or day number not valid or not Gregorian calendar | if 12 < tonumber(month) or 1 > tonumber(month) or 1582 > tonumber(year) or 0 == tonumber(day) then return false; end -- month or day number not valid or not Gregorian calendar | ||
anchor_year = year; | anchor_year = year; | ||
− | + | ||
− | + | -- elseif mw.ustring.match(date_string, patterns['Q,y'][1]) then -- quarter n, year; here because much the same as Mdy | |
− | + | -- month, anchor_year, year=mw.ustring.match(date_string, patterns['Q,y'][1]); | |
− | + | -- if not is_valid_year(year) then return false; end | |
− | + | -- month = get_quarter_number (month, param); -- get quarter number or nil | |
− | + | -- if not month then return false; end -- not valid whatever it is | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
elseif mw.ustring.match(date_string, patterns['Mdy'][1]) then -- month-initial: month day, year | elseif mw.ustring.match(date_string, patterns['Mdy'][1]) then -- month-initial: month day, year | ||
Dòng 541: | Dòng 520: | ||
month = get_month_number (month); | month = get_month_number (month); | ||
if 0 == month then return false; end -- return false if month text isn't one of the twelve months | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
+ | |||
+ | --[[ NOT supported at en.wiki | ||
+ | elseif mw.ustring.match(date_string, patterns['yMd'][1]) then -- year-initial: year month day; day: 1 or 2 two digits, leading zero allowed | ||
+ | anchor_year, year, month, day=mw.ustring.match(date_string, patterns['yMd'][1]); | ||
+ | month = get_month_number (month); | ||
+ | if 0 == month then return false; end -- return false if month text isn't one of the twelve months | ||
+ | -- end NOT supported at en.wiki ]] | ||
elseif mw.ustring.match(date_string, patterns['d-dMy'][1]) then -- day-range-initial: day–day month year; days are separated by endash | elseif mw.ustring.match(date_string, patterns['d-dMy'][1]) then -- day-range-initial: day–day month year; days are separated by endash | ||
Dòng 834: | Dòng 820: | ||
local re_formats = { | local re_formats = { | ||
− | [' | + | ['ymd'] = { -- date format is ymd; reformat to: |
− | [' | + | ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy |
− | [' | + | ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy |
− | + | -- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki | |
}, | }, | ||
− | [' | + | ['Mdy'] = { -- date format is Mdy; reformat to: |
− | [' | + | ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- for long/short reformatting |
− | [' | + | ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy |
− | ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, | + | ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd |
+ | -- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki | ||
}, | }, | ||
− | [' | + | ['dMy'] = { -- date format is dMy; reformat to: |
− | [' | + | ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- for long/short reformatting |
− | [' | + | ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy |
− | [' | + | ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd |
− | + | -- ['yMd'] = {'%s %s %s', 'y', 'm', 'd'}, -- |df=yMd; not supported at en.wiki | |
}, | }, | ||
− | [' | + | ['Md-dy'] = { -- date format is Md-dy; reformat to: |
− | ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, | + | ['mdy'] = {'%s %s–%s, %s', 'm', 'd', 'd2', 'y'}, -- for long/short reformatting |
− | ['dmy'] = {'% | + | ['dmy'] = {'%s–%s %s %s', 'd', 'd2', 'm', 'y'}, -- |df=dmy -> d-dMy |
− | |||
− | |||
− | |||
}, | }, | ||
− | [' | + | ['d-dMy'] = { -- date format is d-d>y; reformat to: |
− | ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, | + | ['dmy'] = {'%s–%s %s %s', 'd', 'd2', 'm', 'y'}, -- for long/short reformatting |
− | ['mdy'] = {'%s % | + | ['mdy'] = {'%s %s–%s, %s', 'm', 'd', 'd2', 'y'}, -- |df=mdy -> Md-dy |
− | |||
− | |||
− | |||
}, | }, | ||
− | ['dMy'] = { | + | ['dM-dMy'] = { -- date format is dM-dMy; reformat to: |
− | ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, | + | ['dmy'] = {'%s %s – %s %s %s', 'd', 'm', 'd2', 'm2', 'y'}, -- for long/short reformatting |
− | ['mdy'] = {'%s %s | + | ['mdy'] = {'%s %s – %s %s, %s', 'm', 'd', 'm2', 'd2', 'y'}, -- |df=mdy -> Md-Mdy |
− | |||
− | |||
− | |||
}, | }, | ||
− | ['Md- | + | ['Md-Mdy'] = { -- date format is Md-Mdy; reformat to: |
− | ['mdy'] = {'%s % | + | ['mdy'] = {'%s %s – %s %s, %s', 'm', 'd', 'm2', 'd2', 'y'}, -- for long/short reformatting |
− | ['dmy'] = {'% | + | ['dmy'] = {'%s %s – %s %s %s', 'd', 'm', 'd2', 'm2', 'y'}, -- |df=dmy -> dM-dMy |
− | |||
}, | }, | ||
− | + | ['dMy-dMy'] = { -- date format is dMy-dMy; reformat to: | |
− | + | ['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- for long/short reformatting | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | ['dMy-dMy'] = { | ||
− | ['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- for long/short reformatting | ||
['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- |df=mdy -> Mdy-Mdy | ['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- |df=mdy -> Mdy-Mdy | ||
− | |||
}, | }, | ||
− | ['Mdy-Mdy'] = { | + | ['Mdy-Mdy'] = { -- date format is Mdy-Mdy; reformat to: |
['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- for long/short reformatting | ['mdy'] = {'%s %s, %s – %s %s, %s', 'm', 'd', 'y', 'm2', 'd2', 'y2'}, -- for long/short reformatting | ||
['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- |df=dmy -> dMy-dMy | ['dmy'] = {'%s %s %s – %s %s %s', 'd', 'm', 'y', 'd2', 'm2', 'y2'}, -- |df=dmy -> dMy-dMy | ||
− | |||
− | |||
− | |||
− | |||
}, | }, | ||
− | [' | + | ['My-My'] = { -- these for long/short reformatting |
− | ['any'] = {'% | + | ['any'] = {'%s %s – %s %s', 'm', 'y', 'm2', 'y2'}, -- dmy/mdy agnostic |
}, | }, | ||
− | ['My'] = { | + | ['M-My'] = { -- these for long/short reformatting |
− | ['any'] = {'%s | + | ['any'] = {'%s–%s %s', 'm', 'm2', 'y'}, -- dmy/mdy agnostic |
}, | }, | ||
− | [' | + | ['My'] = { -- these for long/short reformatting |
− | ['any'] = {'%s %s', 'm', 'y'}, | + | ['any'] = {'%s %s', 'm', 'y'}, -- dmy/mdy agnostic |
}, | }, | ||
+ | -- ['yMd'] = { -- not supported at en.wiki | ||
+ | -- ['mdy'] = {'%s %s, %s', 'm', 'd', 'y'}, -- |df=mdy | ||
+ | -- ['dmy'] = {'%s %s %s', 'd', 'm', 'y'}, -- |df=dmy | ||
+ | -- ['ymd'] = {'%s-%s-%s', 'y', 'm', 'd'}, -- |df=ymd | ||
+ | -- }, | ||
} | } | ||
local function reformatter (date, pattern_idx, format_param, mon_len) | local function reformatter (date, pattern_idx, format_param, mon_len) | ||
− | if not in_array (pattern_idx, { | + | if not in_array (pattern_idx, {'ymd', 'Mdy', 'Md-dy', 'dMy', 'yMd', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy', 'My-My', 'M-My', 'My'}) then |
− | return; | + | return; -- not in this set of date format patterns then not a reformattable date |
end | end | ||
if 'ymd' == format_param and in_array (pattern_idx, {'ymd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy', 'My-My', 'M-My', 'My'}) then | if 'ymd' == format_param and in_array (pattern_idx, {'ymd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy', 'My-My', 'M-My', 'My'}) then | ||
− | return; | + | return; -- ymd date ranges not supported at en.wiki; no point in reformatting ymd to ymd |
end | end | ||
− | if in_array (pattern_idx, {'My', 'M-My', 'My-My'}) then | + | if in_array (pattern_idx, {'My', 'M-My', 'My-My'}) then -- these are not dmy/mdy so can't be 'reformatted' into either |
− | format_param = 'any'; | + | format_param = 'any'; -- so format-agnostic |
end | end | ||
− | if 'yMd' == format_param then -- not supported | + | -- if 'yMd' == format_param and in_array (pattern_idx, {'yMd', 'Md-dy', 'd-dMy', 'dM-dMy', 'Md-Mdy', 'dMy-dMy', 'Mdy-Mdy'}) then -- not supported at en.wiki |
− | return; | + | if 'yMd' == format_param then -- not supported at en.wiki |
+ | return; -- not a reformattable date | ||
end | end | ||
Dòng 936: | Dòng 899: | ||
c1, c2, c3, c4, c5, c6, c7 = mw.ustring.match (date, patterns[pattern_idx][1]); -- get the captures | c1, c2, c3, c4, c5, c6, c7 = mw.ustring.match (date, patterns[pattern_idx][1]); -- get the captures | ||
− | local t = { | + | local t = { -- table that holds k/v pairs of date parts from the captures and patterns[pattern_idx][2..] |
− | [patterns[pattern_idx][2]] = c1; | + | [patterns[pattern_idx][2]] = c1; -- at minimum there is always one capture with a matching indicator letter |
− | [patterns[pattern_idx][3] or 'x'] = c2; | + | [patterns[pattern_idx][3] or 'x'] = c2; -- patterns can have a variable number of captures; each capture requires an indicator letter; |
− | [patterns[pattern_idx][4] or 'x'] = c3; | + | [patterns[pattern_idx][4] or 'x'] = c3; -- where there is no capture, there is no indicator letter so n in patterns[pattern_idx][n] will be nil; |
− | [patterns[pattern_idx][5] or 'x'] = c4; | + | [patterns[pattern_idx][5] or 'x'] = c4; -- the 'x' here spoofs an indicator letter to prevent 'table index is nil' error |
[patterns[pattern_idx][6] or 'x'] = c5; | [patterns[pattern_idx][6] or 'x'] = c5; | ||
[patterns[pattern_idx][7] or 'x'] = c6; | [patterns[pattern_idx][7] or 'x'] = c6; | ||
Dòng 946: | Dòng 909: | ||
}; | }; | ||
− | if t.a then | + | if t.a then -- if this date has an anchor year capture |
− | t.y = t.a; -- use the anchor year capture when reassembling the date | + | t.y = t.a; -- use the anchor year capture when reassembling the date |
end | end | ||
− | if tonumber(t.m) then | + | if tonumber(t.m) then -- if raw month is a number (converting from ymd) |
− | if 's' == mon_len then | + | if 's' == mon_len then -- if we are to use abbreviated month names |
− | t.m = cfg.date_names['inv_local_s'][tonumber(t.m)]; | + | t.m = cfg.date_names['inv_local_s'][tonumber(t.m)]; -- convert it to a month name |
else | else | ||
− | t.m = cfg.date_names['inv_local_l'][tonumber(t.m)]; | + | t.m = cfg.date_names['inv_local_l'][tonumber(t.m)]; -- convert it to a month name |
end | end | ||
t.d = t.d:gsub ('0(%d)', '%1'); -- strip leading '0' from day if present | t.d = t.d:gsub ('0(%d)', '%1'); -- strip leading '0' from day if present | ||
Dòng 963: | Dòng 926: | ||
t.m = string.format ('%02d', get_month_number (t.m)); -- make sure that month and day are two digits | t.m = string.format ('%02d', get_month_number (t.m)); -- make sure that month and day are two digits | ||
t.d = string.format ('%02d', t.d); | t.d = string.format ('%02d', t.d); | ||
− | elseif mon_len then | + | elseif mon_len then -- if mon_len is set to either 'short' or 'long' |
− | for _, mon in ipairs ({'m', 'm2'}) do | + | for _, mon in ipairs ({'m', 'm2'}) do -- because there can be two month names, check both |
if t[mon] then | if t[mon] then | ||
− | t[mon] = get_month_number (t[mon]); | + | t[mon] = get_month_number (t[mon]); -- get the month number for this month (is length agnostic) |
− | if 0 == t[mon] then return; end | + | if 0 == t[mon] then return; end -- seasons and named dates can't be converted |
t[mon] = (('s' == mon_len) and cfg.date_names['inv_local_s'][t[mon]]) or cfg.date_names['inv_local_l'][t[mon]]; -- fetch month name according to length | t[mon] = (('s' == mon_len) and cfg.date_names['inv_local_s'][t[mon]]) or cfg.date_names['inv_local_l'][t[mon]]; -- fetch month name according to length | ||
end | end | ||
Dòng 974: | Dòng 937: | ||
local new_date = string.format (re_formats[pattern_idx][format_param][1], -- format string | local new_date = string.format (re_formats[pattern_idx][format_param][1], -- format string | ||
− | t[re_formats[pattern_idx][format_param][2]], | + | t[re_formats[pattern_idx][format_param][2]], -- named captures from t{} |
t[re_formats[pattern_idx][format_param][3]], | t[re_formats[pattern_idx][format_param][3]], | ||
t[re_formats[pattern_idx][format_param][4]], | t[re_formats[pattern_idx][format_param][4]], | ||
Dòng 1.022: | Dòng 985: | ||
local new_date; | local new_date; | ||
− | if format:match('%a+%-all') then | + | if format:match('%a+%-all') then -- manual df keyword; auto df keyword when length not specified in {{use xxx dates}}; |
format = format:match('(%a+)%-all'); -- extract the format | format = format:match('(%a+)%-all'); -- extract the format | ||
all = true; -- all dates are long format dates because this keyword doesn't specify length | all = true; -- all dates are long format dates because this keyword doesn't specify length |