Module:Calendar/adirni: Difference between revisions

From Nguhcraft Wiki
Jump to navigation Jump to search
Cinthyr (talk | contribs)
i gotta translate these into adirni soon
Cinthyr (talk | contribs)
No edit summary
 
(One intermediate revision by the same user not shown)
Line 10: Line 10:


local month_names = {
local month_names = {
     en = { 'Rebirth', 'Blooming', 'Rains', 'Storms', 'Toads',
     en = { 'Rebirth', 'Blooming', 'Rains', 'Storms', 'Fog',
         'Drying', 'Gathering', 'Grazing', 'Breezes', 'Freezing',
         'Drying', 'Gathering', 'Grazing', 'Breezes', 'Freezing',
         'Darkness', 'Antlers', 'Lanterns', 'Unveiling' },
         'Darkness', 'Antlers', 'Lanterns', 'Unveiling' },
Line 166: Line 166:
     -- todo: implement languages other than english
     -- todo: implement languages other than english
      
      
     -- opts = opts or {}
     opts = opts or {}
     -- opts.lang = opts.lang or "en"
     opts.lang = opts.lang or "en"
     -- opts.length = opts.length or "long"
     opts.length = opts.length or "long"


     -- local date = calendar.to(datestamp)
     local date = calendar.to(datestamp)
     -- local dow = opts.length ~= "none" or
     local dow = opts.length ~= "none" and
    -- day_names[opts.lang][opts.length][date.weekday]
        day_names[opts.lang][opts.length][date.weekday]
     -- local d = opts.
     -- local d = opts.
      
     if dow then
    return string.format("%s %s %s %s", dow,
        return string.format("%s %s %s %s", dow,
         date.day, month_names.en[date.month], date.year)
            date.day, month_names[opts.lang][date.month], date.year)
    else
         return string.format("%s %s %s", date.day,
            month_names[opts.lang][date.month], date.year)
    end
end
end


return calendar
return calendar

Latest revision as of 08:18, 24 May 2026

Documentation for this module may be created at Module:Calendar/adirni/doc

-- if editing this file to fix an error, please keep the maximum line length to
-- strictly 80 characters, even in comments; I edit on small terminals often

local calendar = {}

local equinoxes = require "Module:Calendar/data/equinox_northwards"

local weekdays = { [0] = 1, 2, 3, 4, 5, 6, 7, 1 }
-- 1/1/63374 was on odumso; this is pretty much arbitrary

local month_names = {
    en = { 'Rebirth', 'Blooming', 'Rains', 'Storms', 'Fog',
        'Drying', 'Gathering', 'Grazing', 'Breezes', 'Freezing',
        'Darkness', 'Antlers', 'Lanterns', 'Unveiling' },
    ad_latin = { '1', 'Ḑekḑiņț', '-ré', '-ré', '-ré',
      '6', '7', '8', '-ré', '10',
      'Sorénta', '–ré', '-ré', '14' }
}

local day_names = {
    en = {
    	long = { 'Odumso', 'Dénéso', 'Koșțîșo', 'Malîso', 'Mahnés', 'Heņșîșo',
            'Ursnés' },
        short = { '1ᵒ', '2ᵒ', '3ᵒ', '4ᵒ', '5ˢ', '6ᵒ', '7ˢ' }
    },
    ad_latin = {
    	long = { 'Odumso', 'Dénéso', 'Koșțîșo', 'Malîso', 'Mahnés', 'Heņșîșo',
            'Ursnés' },
        short = { 'I', 'De', 'Ko', 'Na', 'Ma', 'He', 'U' }
    }
}

local function equinox_date(year)
    local datetime = equinoxes[year - 1451]
    -- this would be so much easier if it was indexed with the year

    if not datetime then
        error("northward equinox data for the year " .. year ..
            " doesn't exist")
    end
    assert(datetime.year == year)
    return datetime.hour >= 6 and datetime.day or (datetime.day - 1)
end

local function o(n)
    -- this exists because %o returns *unsigned* octal, which breaks with negative
    -- years (year -1 is outputted as 1777777777777777777777)
    -- with the current breadth of equinox data, though, this probably won't be a
    -- practical issue
    if n >= 0 then
        return string.format("%o", n)
    else
        return string.format("-%o", n)
    end
end

local function melting_length(year)
    -- 1 Rebirth always occurs on the northwards equinox, so we adjust
    -- the length of the month of Melting to make this correspondence true
	
    local gyear = year - 61408 + 1
    -- what gregorian year does February happen in?
    local gleap = (gyear % 4 == 0 and gyear % 100 ~= 0) or gyear % 400 == 0
    local delta = equinox_date(gyear) - equinox_date(gyear - 1)
    -- difference between equinox dates

    return gleap and 21 + delta or 20 + delta
end

local function year_len(year)
    return 345 + melting_length(year)
end

local function month_len(month, year)
    if month == 1 or month == 4 or month == 6 or month == 9 or month == 11
        or month == 13 then
        return 26
    elseif month == 2 or month == 3 or month == 5 or month == 7 or month == 8
        or month == 10 or month == 12 then
        return 27
    elseif month == 14 then
        return melting_length(year)
    else
        error(tostring(month) .. "is not a valid Adirni month")
    end
end

calendar.from = function(date_info)
    assert(date_info.year and date_info.month and date_info.day)

    local date = 78
    -- we choose the fixed point to be the northwards equinox of 1970,
    -- which was 21 March; this is the new year of 63374.
    -- 21/03/1970 has datestamp 79, but the equinox time is before 06:00 utc,
    -- so the actual date in the Adirni calendar is one day earlier.

    if date_info.year >= 63374 then
        local y = date_info.year
        while y > 63374 do
            y = y - 1
            date = date + year_len(y)
        end
        local m = date_info.month
        while m > 1 do
            m = m - 1
            date = date + month_len(m, date_info.year)
        end
        date = date + date_info.day - 1
      else
        date = date - (1 + month_len(date_info.month, date_info.year)
            - date_info.day)
        local m = date_info.month + 1
        local y = date_info.year
        while m <= 14 do
            date = date - month_len(m, y)
            m = m + 1
        end
        while y < 63374 do
            date = date - year_len(y)
            y = y + 1
        end
    end
    return date
end

calendar.to = function(datestamp)
    local dow = weekdays[datestamp % 7]
    local y, m, d = 63374, 1, 1

    datestamp = datestamp - 78
    if datestamp >= 0 then
        while datestamp >= year_len(y) do
            datestamp = datestamp - year_len(y)
            y = y + 1
        end
        while datestamp >= month_len(m, y) do
            datestamp = datestamp - month_len(m, y)
            m = m + 1
        end
        d = d + datestamp
    else
        y, m, d = 63373, 14, 20
        -- the 1969 equinox was on 20/3, while the 1970 equinox was on 21/3
        -- but before 06:00, so the year 63373 is the ordinary 365 days long.
        datestamp = -(datestamp + 1)
        while datestamp >= year_len(y) do
            datestamp = datestamp - year_len(y);
            y = y - 1
        end
        while datestamp >= month_len(m, y) do
            datestamp = datestamp - month_len(m, y)
            m = m - 1
            d = month_len(m, y)
        end
        d = d - datestamp
    end

    return { year = y, month = m, day = d, weekday = dow }
end

calendar.to_formatted = function(datestamp, opts)
    -- en: Ursnés 10 Ḑekḑiņț 63430
    -- ad-latin: Ursnés 12 Ḑekḑiņț 173706
    -- ad: 12 ... 173706
    -- length: "short" is short weekdays, "none" is none, "long" is default
    -- todo: implement languages other than english
    
    opts = opts or {}
    opts.lang = opts.lang or "en"
    opts.length = opts.length or "long"

    local date = calendar.to(datestamp)
    local dow = opts.length ~= "none" and
        day_names[opts.lang][opts.length][date.weekday]
    -- local d = opts.
    if dow then
        return string.format("%s %s %s %s", dow,
            date.day, month_names[opts.lang][date.month], date.year)
    else
        return string.format("%s %s %s", date.day,
            month_names[opts.lang][date.month], date.year)
    end
end

return calendar