Module:Citation/CS1/Date validation: Difference between revisions

    m>Trappist the monk
    (Synch from sandbox;)
    m>Trappist the monk
    (Synch from sandbox;)
    Line 2: Line 2:
    local p = {}
    local p = {}


    -- returns a number according to the month in a date: 1 for January, etc.  Capitalization and spelling must be correct. If not a valid month, returns 0
    --[[--------------------------< I S _ V A L I D _ A C C E S S D A T E >----------------------------------------
     
    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
    today is the current date at time 00:00:00 UTC plus 48 hours
    if today is 2015-01-01T00:00:00 then
    adding 24 hours gives 2015-01-02T00:00:00 – one second more than today
    adding 24 hours gives 2015-01-03T00:00:00 – one second more than tomorrow
     
    ]]
     
    local function is_valid_accessdate (accessdate)
    local lang = mw.getContentLanguage();
    local good1, good2;
    local access_ts, tomorrow_ts; -- to hold unix time stamps representing the dates
    good1, access_ts = pcall( lang.formatDate, lang, 'U', accessdate ); -- convert accessdate value to unix timesatmp
    good2, tomorrow_ts = pcall( lang.formatDate, lang, 'U', 'today + 2 days' ); -- today midnight + 2 days is one second more than all day tomorrow
    if good1 and good2 then
    access_ts = tonumber (access_ts); -- convert to numbers for the comparison
    tomorrow_ts = tonumber (tomorrow_ts);
    else
    return false; -- one or both failed to convert to unix time stamp
    end
    if 979516800 <= access_ts and access_ts < tomorrow_ts then -- Wikipedia start date <= accessdate < tomorrow's date
    return true;
    else
    return false; -- accessdate out of range
    end
    end
     
    --[[--------------------------< G E T _ M O N T H _ N U M B E R >----------------------------------------------
     
    returns a number according to the month in a date: 1 for January, etc.  Capitalization and spelling must be correct. If not a valid month, returns 0
     
    ]]
     
    local function get_month_number (month)
    local function get_month_number (month)
    local long_months = {['January']=1, ['February']=2, ['March']=3, ['April']=4, ['May']=5, ['June']=6, ['July']=7, ['August']=8, ['September']=9, ['October']=10, ['November']=11, ['December']=12};
    local long_months = {['January']=1, ['February']=2, ['March']=3, ['April']=4, ['May']=5, ['June']=6, ['July']=7, ['August']=8, ['September']=9, ['October']=10, ['November']=11, ['December']=12};
    Line 14: Line 55:
    end
    end


    -- returns a number according to the sequence of seasons in a year: 1 for Winter, etc.  Capitalization and spelling must be correct. If not a valid season, returns 0
    --[[--------------------------< G E T _ S E A S O N _ N U M B E R >--------------------------------------------
     
    returns a number according to the sequence of seasons in a year: 1 for Winter, etc.  Capitalization and spelling must be correct. If not a valid season, returns 0
     
    ]]
     
    local function get_season_number (season)
    local function get_season_number (season)
    local season_list = {['Winter']=1, ['Spring']=2, ['Summer']=3, ['Fall']=4, ['Autumn']=4}
    local season_list = {['Winter']=1, ['Spring']=2, ['Summer']=3, ['Fall']=4, ['Autumn']=4}
    Line 22: Line 68:
    return 0; -- misspelled, improper case, or not a season name
    return 0; -- misspelled, improper case, or not a season name
    end
    end
    --[[--------------------------< I S _ P R O P E R _ N A M E >--------------------------------------------------
    returns a non-zero number if date contains a recognized proper name.  Capitalization and spelling must be correct.
    ]]
    local function is_proper_name (name)
    local name_list = {['Christmas']=1}
    local temp;
    temp=name_list[name];
    if temp then return temp; end -- if name is a valid name return its number
    return 0; -- misspelled, improper case, or not a proper name
    end
    --[[--------------------------< I S _ V A L I D _ M O N T H _ O R _ S E A S O N >------------------------------


    --returns true if month or season is valid (properly spelled, capitalized, abbreviated)
    --returns true if month or season is valid (properly spelled, capitalized, abbreviated)
    ]]
    local function is_valid_month_or_season (month_season)
    local function is_valid_month_or_season (month_season)
    if 0 == get_month_number (month_season) then -- if month text isn't one of the twelve months, might be a season
    if 0 == get_month_number (month_season) then -- if month text isn't one of the twelve months, might be a season
    Line 143: Line 208:
    end
    end


    --[[
    --[[--------------------------< C H E C K _ D A T E >----------------------------------------------------------
     
    Check date format to see that it is one of the formats approved by WP:DATESNO or WP:DATERANGE. Exception: only allowed range separator is endash.
    Check date format to see that it is one of the formats approved by WP:DATESNO or WP:DATERANGE. Exception: only allowed range separator is endash.
    Additionally, check the date to see that it is a real date: no 31 in 30-day months; no 29 February when not a leap year.  Months, both long-form and three
    Additionally, check the date to see that it is a real date: no 31 in 30-day months; no 29 February when not a leap year.  Months, both long-form and three
    Line 254: Line 320:
    end
    end
    elseif date_string:match("^%a+ +%d%d%d%d%a?$") then -- month/season year
    elseif date_string:match("^%a+ +%d%d%d%d%a?$") then -- month/season year or proper-name year
    month, anchor_year, year=date_string:match("(%a+)%s*((%d%d%d%d)%a?)");
    month, anchor_year, year=date_string:match("(%a+)%s*((%d%d%d%d)%a?)");
    if not is_valid_year(year) then return false; end
    if not is_valid_year(year) then return false; end
    if not is_valid_month_or_season (month) then return false; end
    if not is_valid_month_or_season (month) and 0 == is_proper_name (month) then return false; end


    elseif date_string:match("^[1-9]%d%d%d?–[1-9]%d%d%d?%a?$") then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
    elseif date_string:match("^[1-9]%d%d%d?–[1-9]%d%d%d?%a?$") then -- Year range: YYY-YYY or YYY-YYYY or YYYY–YYYY; separated by unspaced endash; 100-9999
    Line 345: Line 411:
    else
    else
    good_date, anchor_year, COinS_date = check_date (v); -- go test the date
    good_date, anchor_year, COinS_date = check_date (v); -- go test the date
    end
    elseif 'accessdate'==k then -- if the parameter is |date=
    good_date = check_date (v); -- go test the date
    if true == good_date then -- if the date is a valid date
    good_date = is_valid_accessdate (v); -- is Wikipedia start date < accessdate < tomorrow's date?
    end
    end
    else -- any other date-holding parameter
    else -- any other date-holding parameter