Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:Sandbox/DixonD/Datetime/Julian

From Wikipedia, the free encyclopedia
local Error = require('Module:Error');

local this = {};

function this.julianDayOfDate(date)
    -- http://www.tondering.dk/claus/cal/julperiod.php#formula
    local y = date.year + 4799;                     -- Set epoch in 1 March -4800, but counting months from January as the 10th month of previous year.
    local m = y * 12 + date.month + 9;              -- Total number of months since epoch (January = 10, December = 21).
    y = math.floor(m / 12); m = m - y * 12;         -- Split total months into relative months...
    return
          math.floor(y * 1461 / 4)                  -- Julian cycle of 1461 days every 4 years.
        + math.floor((m + 4) * 153 / 5)             -- Days in relative month (need to substract 122 at end).
        + date.day                                  -- Additional days (need to substract 1 at end).
        + (date.hour - 12) / 24                     -- The time part.
        + date.minute / 1440
        + date.second / 86400                       -- (leap seconds ignored, every day assumed to be 86400 seconds exactly).
        - 32204;                                    -- Final substractive constant 32204 == 32081 + 122 + 1.
end;

function this.dateOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    local date = {};
    date.weekday = JD + 0.5 - math.floor((JD + 0.5) / 7) * 7; -- 0 = Monday, 6 = Sunday.
 
    -- See [[fr:Formules de calcul du calendrier grégorien]] on Wikipedia for explained details and intermediate values in test cases.
    JD = JD + 32081.5;
    local j = math.floor(JD); -- no rounding performed for the precision of time; if you need it, round the JD before calling this method.
 
    -- 1461 days per cycle of 4 years (no adjustment needed).
    local b  = math.floor(dc / 1461);
    local db = dc - b * 1461;
 
    -- 365 days per cycle of 1 year (cycle numbers: 0 to 4; but 4 is reduced to 3, making sometimes the last cycle longer longer by 1 day).
    -- Note: for a in 0..4: math.min(a, 3) is equal to math.floor((a * 3 + 1) / 4); this avoids conditional branches:
    --       0 -> 0 = floor(1 / 4); 1 -> 1 = floor(4 / 4); 2 -> 2 = floor(7 / 4); 3 -> 3 = floor(10 / 4); 4 -> 4 = floor(13 / 4)
    local a  = math.floor((math.floor(db / 365) * 3 + 1) / 4);
    local da = db - a * 365;
 
    -- Relative date since epoch (1 March -4800).
    local y = b * 4 + a;
    local m = math.floor((da * 5 + 308) / 153) - 2;
    local d = da - math.floor((m + 4) * 153 / 5) + 122;
 
    -- Actual Julian date.
    date.year   = y - 4800 + math.floor((m + 2) / 12);
    date.month  = m - math.floor((m + 2) / 12) * 12 + 3;
    date.day    = d + 1;--//Test:1
 
    -- Actual time of day (leap seconds ignored, every day assumed to be 86400 seconds exactly).
    j = (JD + 0.5 - math.floor(JD + 0.5)) * 24;
    date.hour   = math.floor(j);
    j = (j - date.hour) * 60;
    date.minute = math.floor(j);
    date.second = (j - date.minute) * 60; -- No rounding performed; this includes fractions of seconds.
    return date;
end;
 
function this.julianDay(year, month, day, hour, minute, second)
    -- Check parameters and set defaults.
    if year == nil then
        return Error.error{"Parameter 1=''year'' is either missing or has wrong format!"};
    end; 
    if month  == nil then month  = 1;  end;
    if day    == nil then day    = 1;  end;
    if hour   == nil then hour   = 12; end;
    if minute == nil then minute = 0;  end;
    if second == nil then second = 0;  end;
    return this.julianDayOfDate({year = year, month = month, day = day, hour = hour, minute = minute, second = second});
end;

-- Basic formatting (for debugging only ?).
function this.wikiDateOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    local date = this.dateOfJulianDay(JD);
    return        tostring(date.year)
        .. "|" .. tostring(date.month)
        .. "|" .. tostring(date.day)
        .. "|" .. tostring(date.hour)
        .. "|" .. tostring(date.minute)
        .. "|" .. tostring(date.second);
end;
 
-- English formatting (for display or tests ? not internationalized).
function this.EnglishDateOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    local date = this:dateOfJulianDay(JD);
    
    local s = "";
    if (date >= 0 and date.day < 10) then
        s = s .. "0" .. tostring(date.day);
    else
        s = s ..        tostring(date.day);
    end
    local months = {
        "January", "February", "March", "April", "May", "June",
        "July", "August", "September", "October", "November", "December"
    };
    s = s .. " " .. months[date.month - 1] .. " ";
    if (date.year < 0) then
        s = s .. tostring(1 - date.year) .. " BC ";
    else
        s = s .. tostring(date.year)     .. " AD ";
    end
    if (date.hour >= 0 and date.hour < 10) then
        s = s .. "0" .. tostring(date.hour) .. ":";
    else
        s = s ..        tostring(date.hour) .. ":";
    end
    if (date.minute >= 0 and date.minute < 10) then
        s = s .. "0" .. tostring(date.minute) .. ":";
    else
        s = s ..        tostring(date.minute) .. ":";
    end
    if (date.second >= 0 and date.second < 10) then
        s = s .. "0" .. tostring(date.second);
    else
        s = s ..        tostring(date.second);
    end
    return s .. " UTC";
end;
 
function this.yearOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    return this.dateOfJulianDay(JD).year;
end;
 
function this.monthOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    return this.dateOfJulianDay(JD).month;
end;
 
function this.dayOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    return this.dateOfJulianDay(JD).day;
end;
 
function this.weekdayOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    return this.dateOfJulianDay(JD).weekday;
end;
 
function this.hourOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    return this.dateOfJulianDay(JD).hour;
end;
 
function this.minuteOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    return this.dateOfJulianDay(JD).minute;
end;
 
function this.secondOfJulianDay(JD)
    -- Check parameters.
    if JD == nil then
        return Error.error{"Parameter 1=''Julian day'' is either missing or has wrong format!"};
    end;
 
    return this.dateOfJulianDay(JD).second;
end;

return this;