Module:Nepali date: Difference between revisions
Jump to navigation
Jump to search
Content deleted Content added
fix |
Remove ISO |
||
| Line 281: | Line 281: | ||
end |
end |
||
-- Main public function: AD -> BS ( |
-- Main public function: AD -> BS (Nepali style) |
||
function p.ad2bs(frame) |
function p.ad2bs(frame) |
||
local args = frame.args or {} |
local args = frame.args or {} |
||
| Line 287: | Line 287: | ||
local m = tonumber(args.month) or tonumber(args[2]) |
local m = tonumber(args.month) or tonumber(args[2]) |
||
local d = tonumber(args.day) or tonumber(args[3]) |
local d = tonumber(args.day) or tonumber(args[3]) |
||
local fmt = args.format or "iso" |
|||
if not valid_ad_date(y, m, d) then |
if not valid_ad_date(y, m, d) then |
||
| Line 302: | Line 301: | ||
end |
end |
||
| ⚫ | |||
if fmt == "nepali" then |
|||
local ad_month_name = np_ad_months[m] or tostring(m) |
|||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
to_nepali_digits(bs_y), bs_month_name, to_nepali_digits(bs_d) |
|||
| ⚫ | |||
| ⚫ | |||
| ⚫ | |||
else |
|||
return string.format("%04d-%02d-%02d (वि.सं. %04d-%02d-%02d)", |
|||
y, m, d, bs_y, bs_m, bs_d |
|||
) |
|||
end |
|||
end |
end |
||
Latest revision as of 12:36, 17 September 2025
Documentation for this module may be created at Module:Nepali date/doc
-- Module:Nepali date
-- Accurate AD -> BS conversion using lookup table for BS years 1975..2099.
-- Base reference: AD 1943-04-14 = BS 2000-01-01
local p = {}
-- Nepali month names (Baisakh..Chaitra)
local np_months = {
"वैशाख","जेठ","असार","साउन","भदौ","असोज",
"कात्तिक","मङ्सिर","पुष","माघ","फागुन","चैत"
}
-- Nepali month names for AD (Gregorian months)
local np_ad_months = {
"जनवरी","फेब्रुअरी","मार्च","अप्रिल","मे","जुन",
"जुलाई","अगस्ट","सेप्टेम्बर","अक्टोबर","नोभेम्बर","डिसेम्बर"
}
-- convert ascii digits to nepali digits
local nep_digits = {["0"]="०",["1"]="१",["2"]="२",["3"]="३",["4"]="४",["5"]="५",["6"]="६",["7"]="७",["8"]="८",["9"]="९"}
local function to_nepali_digits(num)
return tostring(num):gsub("%d", function(d) return nep_digits[d] end)
end
-- ========== BS table (1975..2099) ==========
-- Each entry: {Baisakh, Jestha, Asar, Shravan, Bhadra, Ashwin, Kartik, Mangsir, Poush, Magh, Falgun, Chaitra, total_days}
local bs_table = {}
bs_table[1975] = {31, 31, 32, 32, 31, 30, 30, 29, 30, 29, 30, 30, 365}
bs_table[1976] = {31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 31, 366}
bs_table[1977] = {30, 32, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31, 365}
bs_table[1978] = {31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30, 365}
bs_table[1979] = bs_table[1975]
bs_table[1980] = bs_table[1976]
bs_table[1981] = {31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 29, 31, 365}
bs_table[1982] = bs_table[1978]
bs_table[1983] = bs_table[1975]
bs_table[1984] = bs_table[1976]
bs_table[1985] = {31, 31, 31, 32, 31, 31, 29, 30, 30, 29, 30, 30, 365}
bs_table[1986] = bs_table[1978]
bs_table[1987] = {31, 32, 31, 32, 31, 30, 30, 29, 30, 29, 30, 30, 365}
bs_table[1988] = bs_table[1976]
bs_table[1989] = {31, 31, 31, 32, 31, 31, 30, 29, 30, 29, 30, 30, 365}
bs_table[1990] = bs_table[1978]
bs_table[1991] = {31, 32, 31, 32, 31, 30, 30, 30, 29, 29, 30, 30, 365}
bs_table[1992] = {31, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31, 366}
bs_table[1993] = bs_table[1989]
bs_table[1994] = bs_table[1978]
bs_table[1995] = bs_table[1991]
bs_table[1996] = bs_table[1992]
bs_table[1997] = bs_table[1978]
bs_table[1998] = {31, 31, 32, 31, 32, 30, 30, 29, 30, 29, 30, 30, 365}
bs_table[1999] = bs_table[1976]
bs_table[2000] = {30, 32, 31, 32, 31, 30, 30, 30, 29, 30, 29, 31, 365}
bs_table[2001] = bs_table[1978]
bs_table[2002] = bs_table[1975]
bs_table[2003] = bs_table[1976]
bs_table[2004] = bs_table[2000]
bs_table[2005] = bs_table[1978]
bs_table[2006] = bs_table[1975]
bs_table[2007] = bs_table[1976]
bs_table[2008] = bs_table[1981]
bs_table[2009] = bs_table[1978]
bs_table[2010] = bs_table[1975]
bs_table[2011] = bs_table[1976]
bs_table[2012] = bs_table[1985]
bs_table[2013] = bs_table[1978]
bs_table[2014] = bs_table[1975]
bs_table[2015] = bs_table[1976]
bs_table[2016] = bs_table[1985]
bs_table[2017] = bs_table[1978]
bs_table[2018] = bs_table[1987]
bs_table[2019] = bs_table[1992]
bs_table[2020] = bs_table[1989]
bs_table[2021] = bs_table[1978]
bs_table[2022] = bs_table[1991]
bs_table[2023] = bs_table[1992]
bs_table[2024] = bs_table[1989]
bs_table[2025] = bs_table[1978]
bs_table[2026] = bs_table[1976]
bs_table[2027] = bs_table[2000]
bs_table[2028] = bs_table[1978]
bs_table[2029] = bs_table[1998]
bs_table[2030] = bs_table[1976]
bs_table[2031] = bs_table[2000]
bs_table[2032] = bs_table[1978]
bs_table[2033] = bs_table[1975]
bs_table[2034] = bs_table[1976]
bs_table[2035] = bs_table[1977]
bs_table[2036] = bs_table[1978]
bs_table[2037] = bs_table[1975]
bs_table[2038] = bs_table[1976]
bs_table[2039] = bs_table[1985]
bs_table[2040] = bs_table[1978]
bs_table[2041] = bs_table[1975]
bs_table[2042] = bs_table[1976]
bs_table[2043] = bs_table[1985]
bs_table[2044] = bs_table[1978]
bs_table[2045] = bs_table[1987]
bs_table[2046] = bs_table[1976]
bs_table[2047] = bs_table[1989]
bs_table[2048] = bs_table[1978]
bs_table[2049] = bs_table[1991]
bs_table[2050] = bs_table[1992]
bs_table[2051] = bs_table[1989]
bs_table[2052] = bs_table[1978]
bs_table[2053] = bs_table[1991]
bs_table[2054] = bs_table[1992]
bs_table[2055] = bs_table[1978]
bs_table[2056] = bs_table[1998]
bs_table[2057] = bs_table[1976]
bs_table[2058] = bs_table[2000]
bs_table[2059] = bs_table[1978]
bs_table[2060] = bs_table[1975]
bs_table[2061] = bs_table[1976]
bs_table[2062] = {30, 32, 31, 32, 31, 31, 29, 30, 29, 30, 29, 31, 365}
bs_table[2063] = bs_table[1978]
bs_table[2064] = bs_table[1975]
bs_table[2065] = bs_table[1976]
bs_table[2066] = bs_table[1981]
bs_table[2067] = bs_table[1978]
bs_table[2068] = bs_table[1975]
bs_table[2069] = bs_table[1976]
bs_table[2070] = bs_table[1985]
bs_table[2071] = bs_table[1978]
bs_table[2072] = bs_table[1987]
bs_table[2073] = bs_table[1976]
bs_table[2074] = bs_table[1989]
bs_table[2075] = bs_table[1978]
bs_table[2076] = bs_table[1991]
bs_table[2077] = bs_table[1992]
bs_table[2078] = bs_table[1989]
bs_table[2079] = bs_table[1978]
bs_table[2080] = bs_table[1991]
bs_table[2081] = bs_table[1992]
bs_table[2082] = bs_table[1989]
bs_table[2083] = bs_table[1978]
bs_table[2084] = bs_table[1976]
bs_table[2085] = bs_table[2000]
bs_table[2086] = bs_table[1978]
bs_table[2087] = bs_table[1975]
bs_table[2088] = bs_table[1976]
bs_table[2089] = bs_table[2000]
bs_table[2090] = bs_table[1978]
bs_table[2091] = bs_table[1975]
bs_table[2092] = bs_table[1976]
bs_table[2093] = bs_table[1981]
bs_table[2094] = bs_table[1978]
bs_table[2095] = bs_table[1975]
bs_table[2096] = bs_table[1976]
bs_table[2097] = bs_table[1985]
bs_table[2098] = bs_table[1978]
bs_table[2099] = bs_table[1975]
-- ========== End of BS table ==========
-- Gregorian month days
local function days_in_gregorian_month(y, m)
local mdays = {31,28,31,30,31,30,31,31,30,31,30,31}
if m == 2 then
if (y % 400 == 0) or (y % 4 == 0 and y % 100 ~= 0) then
return 29
else
return 28
end
else
return mdays[m]
end
end
-- AD next day
local function ad_next(y, m, d)
d = d + 1
local mdays = days_in_gregorian_month(y, m)
if d > mdays then
d = 1
m = m + 1
if m > 12 then
m = 1
y = y + 1
end
end
return y, m, d
end
-- AD previous day
local function ad_prev(y, m, d)
d = d - 1
if d < 1 then
m = m - 1
if m < 1 then
m = 12
y = y - 1
end
d = days_in_gregorian_month(y, m)
end
return y, m, d
end
-- compare AD dates
local function compare_ad(a_y, a_m, a_d, b_y, b_m, b_d)
if a_y < b_y then return -1 elseif a_y > b_y then return 1 end
if a_m < b_m then return -1 elseif a_m > b_m then return 1 end
if a_d < b_d then return -1 elseif a_d > b_d then return 1 end
return 0
end
-- Base references
local base_ad = { year = 1943, month = 4, day = 14 }
local base_bs = { year = 2000, month = 1, day = 1 }
-- Days difference from base AD
local function days_diff_from_base(target_y, target_m, target_d)
local dir = compare_ad(base_ad.year, base_ad.month, base_ad.day, target_y, target_m, target_d)
local forward = dir <= 0
if dir == 0 then return 0 end
local y, m, d = base_ad.year, base_ad.month, base_ad.day
local steps = 0
if forward then
while not (y == target_y and m == target_m and d == target_d) do
y, m, d = ad_next(y, m, d)
steps = steps + 1
if steps > 200000 then return nil, "date range too large" end
end
return steps
else
while not (y == target_y and m == target_m and d == target_d) do
y, m, d = ad_prev(y, m, d)
steps = steps - 1
if steps < -200000 then return nil, "date range too large" end
end
return steps
end
end
-- Walk BS calendar from base by offset
local function bs_from_offset(offset)
local y, m, d = base_bs.year, base_bs.month, base_bs.day
if offset == 0 then return y, m, d end
if offset > 0 then
for i = 1, offset do
local months = bs_table[y]
if not months then return nil, "missing bs_table for year "..y end
d = d + 1
if d > months[m] then
d = 1
m = m + 1
if m > 12 then
m = 1
y = y + 1
end
end
end
else
for i = 1, math.abs(offset) do
d = d - 1
if d < 1 then
m = m - 1
if m < 1 then
m = 12
y = y - 1
end
local months = bs_table[y]
if not months then return nil, "missing bs_table for year "..y end
d = months[m]
end
end
end
return y, m, d
end
-- Validate AD date
local function valid_ad_date(y, m, d)
if not (y and m and d) then return false end
if m < 1 or m > 12 then return false end
local mdays = days_in_gregorian_month(y, m)
if d < 1 or d > mdays then return false end
return true
end
-- Main public function: AD -> BS (Nepali style)
function p.ad2bs(frame)
local args = frame.args or {}
local y = tonumber(args.year) or tonumber(args[1])
local m = tonumber(args.month) or tonumber(args[2])
local d = tonumber(args.day) or tonumber(args[3])
if not valid_ad_date(y, m, d) then
return "Error: provide valid AD year, month, day"
end
local offset, err = days_diff_from_base(y, m, d)
if not offset then return "Error computing day offset: "..tostring(err) end
local bs_y, bs_m, bs_d, err2 = bs_from_offset(offset)
if not bs_y then return "Error computing BS date: "..tostring(bs_m) end
if bs_y < 1975 or bs_y > 2099 then
return "Error: date out of supported BS range (1975–2099)"
end
local bs_month_name = np_months[bs_m] or tostring(bs_m)
local ad_month_name = np_ad_months[m] or tostring(m)
return string.format(
"%s %s %s (वि.सं. %s %s %s)",
to_nepali_digits(d), ad_month_name, to_nepali_digits(y),
to_nepali_digits(bs_y), bs_month_name, to_nepali_digits(bs_d)
)
end
function p.convert(frame) return p.ad2bs(frame) end
return p