Jump to content

Module:Japanese calendar

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Mr. Stradivarius (talk | contribs) at 07:34, 22 August 2013 (allow getting the era year for the first year of the next era (e.g. Taisho 14 is also Showa 1 )). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local eras = mw.loadData( 'Module:Japanese calendar/data' )

--------------------------------------------------------------------
-- Helper functions
--------------------------------------------------------------------

local function yearToEraIndex( year )
    local currentYear = tonumber( mw.language.getContentLanguage():formatDate( 'Y' ) )
    year = tonumber( year )
    if type( year ) ~= 'number' or year > currentYear then return end
    for i, t in ipairs( eras ) do
        if year >= t.year then
            return i
        end
    end
end

local function textToEraIndex( s )
    for i, t in ipairs( eras ) do
        if s == t.article or s == t.kanji then
            return i
        end
    end
end

--------------------------------------------------------------------
-- Era class definition
--------------------------------------------------------------------

local era = {}
era.__index = era

function era:new( init )
    init = type( init ) == 'table' and init or {}
    local obj = {}
    
    -- Grab the data from the init table.
    obj.gregorianYear = tonumber( init.year )
    obj.article = type( init.article ) == 'string' and init.article or nil
    obj.kanji = type( init.kanji ) == 'string' and init.kanji or nil
    
    -- Calculate the era data from the input. Some input values may be overwritten if they are inconsistent with the data in the /data subpage.
    -- If the article name and the kanji differ, the article name takes priority.
    if obj.gregorianYear then
        -- We have the Gregorian year, so we can calculate all the data.
        -- Check if the article or the kanji have been specified, in case the era is different from the year era.
        local eraIndex
        if obj.article or obj.kanji then
            eraIndex = textToEraIndex( obj.article ) or textToEraIndex( obj.kanji )
        else
            eraIndex = yearToEraIndex( obj.gregorianYear )
        end
        
        if eraIndex then
            local eraData = eras[ eraIndex ]
            obj.startYear = eraData.year
            -- Allow matching years to different eras, but only for the first year of the next era. For example, Taisho 14 is also Showa 1, but there is no such thing as Taisho 15.
            if eraIndex > 1 then
                local nextEraData = eras[ eraIndex - 1 ]
                local nextStartYear = nextEraData.year
                if obj.gregorianYear <= nextStartYear and obj.gregorianYear >= obj.startYear and math.floor( obj.gregorianYear ) ~= 687 then -- 686 is a special case as the Shuchō era lasted for less than one year. Disallowing 687 is a quick fix for this.
                    obj.eraYear = obj.gregorianYear - obj.startYear + 1
                    obj.eraYearKanji = tostring( obj.eraYear ) -- Although most of these will be numbers, one is a kanji character, so convert them all to strings.
                    if obj.eraYearKanji == '1' then
                        obj.eraYearKanji = '元'
                    end
                end
            end
            
            obj.article = eraData.article
            obj.kanji = eraData.kanji
            obj.label = eraData.label
        end
    
    elseif obj.article or obj.kanji then
        -- No year was specified, so we will take what data we can from the article name or from the kanji.
        local eraIndex = textToEraIndex( obj.article ) or textToEraIndex( obj.kanji )
        if eraIndex then
            local eraData = eras[ eraIndex ]
            obj.startYear = eraData.year
            obj.kanji = eraData.kanji
            obj.label = eraData.label
        end
    end
    -- Create a link to the era article if possible.
    if obj.article then
        if obj.label then
            obj.link = mw.ustring.format( '[[%s|%s]]', obj.article, obj.label )
        else
            obj.link = mw.ustring.format( '[[%s]]', obj.article )
        end
    end
    
    return setmetatable( obj, {
        __index = self
    })
end

return era