Lua
CodeDiscussionEditHistoryLinksLink count Subpages:DocumentationTestsResultsSandboxLive code All modules
This module is rated as ready for general use. It has reached a mature form and is thought to be bug-free and ready for use wherever appropriate. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This module is intended for processing of date strings. Currently used by:
It relies on Module:DateI18n
This function is the engine behind {{ISOdate}}. Please see that template for full documentation
Usage:
Parameters:
|date=date
or|1=date
|class=class
<span class="class" lang="lang" dir="ltr or rtl">...</span>
element with this class, also tagging the specified language and its direction (by default, use |class=dtime
, as defined in microformats); set it to an empty value to remove this invisible HTML tag; this microtag is also not emitted if the given date cannot be parsed with one of the supported formats and its value will be returned as is.|lang=lang
lang="lang"
attribute of HTML)|case=case
|trim_year=flag
This function is the engine behind {{ISOyear}}. Please see that template for full documentation
Usage:
Parameters:
Modules related to internationalization (i18n) of dates | ||||
---|---|---|---|---|
{| class="wikitable sortable" border="1" | ||||
Module Name | Uses Module | Used by Module | Used by Template | Comment |
Module:DateI18n | Module:I18n/date | Module:ISOdate | Template:Date | Create date string in any language |
Module:ISOdate | Module:DateI18n | Module:Complex date | Template:ISOdate & Template:ISOyear | Parse YYYY-MM-DD date string |
Module:Roman | Module:Complex date Module:Ordinal |
Template:Roman | Create Roman numerals | |
Module:Ordinal | Module:I18n/ordinal Module:Roman |
Module:Complex date | Template:Ordinal | Create Ordinal numerals |
Module:Complex date | Module:I18n/complex date Module:ISOdate Module:Roman Module:Ordinal |
Template:Other date (not deployed yet) | Create complex date phrases in many languages |
|}
--[[
__ __ _ _ ___ ____ ___ _ _
| \/ | ___ __| |_ _| | ___ _|_ _/ ___| / _ \ __| | __ _| |_ ___
| |\/| |/ _ \ / _` | | | | |/ _ (_)| |\___ \| | | |/ _` |/ _` | __/ _ \
| | | | (_) | (_| | |_| | | __/_ | | ___) | |_| | (_| | (_| | || __/
|_| |_|\___/ \__,_|\__,_|_|\___(_)___|____/ \___/ \__,_|\__,_|\__\___|
This module is intended for processing of date strings.
Please do not modify this code without applying the changes first at Module:ISOdate/sandbox and testing
at Module:ISOdate/sandbox/testcases and Module talk:ISOdate/sandbox/testcases.
Authors and maintainers:
* User:Parent5446 - original version of the function mimicking template:ISOdate
* User:Jarekt - original version of the functions mimicking template:Date and template:ISOyear
]]
-- =======================================
-- === Dependencies ======================
-- =======================================
local Date = require('Module:DateI18n')._Date
-- =======================================
-- === Local Functions ===================
-- =======================================
local function parse_ISOdate(datestr)
-- Core function of this module, which splits "datestr" contining date in ISO format into Year, month, day, ... components
-- Output is "datevec" array with numbers representing date components. We also return "tail" storing text following the date
-- pattern: regexp - regular expresion to test; dlen - number of date elements; tail = which element is a "tail" if any
-- regexp hints:
-- 1) Strings starting with "^" and ending with "$" indicate whole string match
-- 2) optional tail part copied as-is and following the main parsed part of the date have to be separated from the date by a whitespace, so "(\s.+)?"
local patterns = {
-- strings starting with YYYY-MM-DD HH:MM:SS. Year 4 digits (if we know seconds than it was within the last 100 years), the rest 1-2
-- date and time can be separated by space or "T" and there could be a "Z" on the end indicating "Zulu" time zone
{dlen=6, tail=7, regexp="^+?(%d%d%d%d)-(%d%d?)-(%d%d?)[T](%d%d?):(%d%d?):(%d%d?)Z?(%s.*)"},
{dlen=6, tail=0, regexp="^+?(%d%d%d%d)-(%d%d?)-(%d%d?)[T](%d%d?):(%d%d?):(%d%d?)Z?$"},
-- strings starting with YYYY-MM-DD HH:MM. Year 4 digits, the rest 1-2
-- (if one knows hour and minute than it was probably after a year 1000)
{dlen=5, tail=6, regexp="^+?(%d%d%d%d)-(%d%d?)-(%d%d?)[T](%d%d?):(%d%d?)(%s.+)"},
{dlen=5, tail=0, regexp="^+?(%d%d%d%d)-(%d%d?)-(%d%d?)[T](%d%d?):(%d%d?)$"},
-- strings starting with YYYY-MM-DD. Year 1-4 digits, the rest 1-2
{dlen=3, tail=4, regexp="^+?(%d%d?%d?%d?)-(%d%d?)-(%d%d?)(%s.+)"},
{dlen=3, tail=0, regexp="^+?(%d%d?%d?%d?)-(%d%d?)-(%d%d?)$"},
-- strings starting with YYYY-MM. Year 3-4 digits, month 2 digits
-- (want to avoit converting to dates strings like 10-5 = 5
{dlen=2, tail=3, regexp="^+?(%d%d%d%d?)-(%d%d)(%s.+)"},
-- if whole string is in YYYY-MM form: If Year 1-4 digits, month 1-2 digits
{dlen=2, tail=0, regexp="^+?(%d%d?%d?%d?)-(%d%d?)$"},
-- string starts with a number -> it has to be 3 or 4 digit long to be a year
{dlen=1, tail=2, regexp="^+?(%d%d%d%d?)(%s.+)"},
-- if whole string is a number (1-4 digit long) than it will be interpreted as a year
{dlen=1, tail=0, regexp="^+?(%d%d?%d?%d?)$"},
}
-- create datevec based on which variables are provided
local datevec = {}
local tail = ''
for i, pat in ipairs( patterns ) do
local vec = {datestr:match( pat.regexp )}
if vec and vec[1]~=nil then
for j=1, pat.dlen do
datevec[j] = vec[j]
end
if pat.tail>0 and vec[pat.tail]~=nil then
tail = mw.ustring.gsub(' ' .. vec[pat.tail], ' +', ' ')
end
break
end
end
if not datevec[1] or datevec[1]=='' then
-- quickly return if datestr does not look like date (it could be a template)
return nil, nil
end
return datevec, tail
end
-- ==================================================
-- === External functions ===========================
-- ==================================================
local p = {}
-- ===========================================================================
-- === Version of the function to be called from other LUA codes
-- ===========================================================================
function p._ISOyear( datestr )
-- if empty string then return it
datestr = mw.text.trim(datestr or '' )
if datestr == '' then
return ''
end
-- if number then return it
if tonumber( datestr ) then
return mw.ustring.format( '%04i', datestr )
end
-- otherwise use regular expression match
datestr = mw.ustring.match( datestr, '^+?(-?%d%d?%d?%d?)-' )
if datestr and tonumber( datestr ) then
return mw.ustring.format( '%04i', datestr )
else
return ''
end
end
function p._ISOdate(datestr, lang, case, class, trim_year)
datestr = mw.text.trim(datestr or '' )
local datevec, tail = parse_ISOdate(datestr)
if not datevec then
return datestr, false -- quickly return if datestr does not look like date (it could be a template)
end
-- call p._Date function to format date string
local datestr2 = Date(datevec, lang, case, class, trim_year)
if datestr2~='' then
return mw.text.trim( datestr2 .. tail), true
else -- in case of errors return the original string
return datestr, false
end
end
-- ===========================================================================
-- === Versions of the function to be called from template namespace
-- ===========================================================================
--[[
ISOdate
This function is the core part of the ISOdate template.
Usage:
{{#invoke:ISOdate|ISOdate|target_string|lang=}}
Parameters:
1: The date string
lang: The language to display it in
form: Language format (genitive, etc.) for some languages
class: CSS class for the <time> node
Error Handling:
If the string does not look like it contain the proper ISO date than the function will return the original string.
That is the preferred treatment for the template:Information (and similar templates) which calling it.
]]
function p.ISOdate(frame)
local args = {}
for name, value in pairs( frame.args ) do
if value ~= '' then -- nuke empty strings
if type(name)=='string' then
name = string.gsub( string.lower(name), ' ', '_')
end
args[name] = value
end
end
local datestr, succeded = p._ISOdate(
args[1] or '',
args.lang, -- language
args.case, -- allows to specify grammatical case for the month for languages that use them
args.class or 'dtstart', -- allows to set the html class of the time node where the date is included.
args.trim_year or '100-999' -- by default pad one and 2 digit years to be 4 digit long, while keeping 3 digit years as is
)
return datestr
end
--[[
ISOyear
This function returns year part of date string.
Usage:
{{#invoke:ISOdate|ISOyear|target_string}}
Parameters
1: The date string
Error Handling:
If the string does not look like it contain the year than the function will not return anything.
That is the preferred treatment for the template:Creator which is the main (only?) template calling it.
]]
function p.ISOyear( frame )
return p._ISOyear( frame.args[1] )
end
return p