Difference between revisions of "Module:D'ni Time"

m
m
 
(9 intermediate revisions by the same user not shown)
Line 2: Line 2:
  
 
dnitools = require("Module:D'ni Tools")
 
dnitools = require("Module:D'ni Tools")
 +
dnifunc = require("Module:D'ni Time/dni")
 +
surfacefunc = require("Module:D'ni Time/surface")
 +
 
Date = require('Module:Date')._Date
 
Date = require('Module:Date')._Date
  
Line 16: Line 19:
 
local msPerProrahn = msPerHahr / prorahnteePerHahr
 
local msPerProrahn = msPerHahr / prorahnteePerHahr
 
local refProrahnteePerHahr = 9647 * 290 * 5 * 25 * 25 * 25
 
local refProrahnteePerHahr = 9647 * 290 * 5 * 25 * 25 * 25
 
local vaileetee = {"Leefo","Leebro","Leesahn","Leetar","Leevot","Leevofo","Leevobro","Leevosahn","Leevotar","Leenovoo"}
 
local vaileetee_dnifont = {"lEfo","lEbro","lEsan","lEtar","lEvot","lEvofo","lEvobro","lEvosan","lEvotar","lEnovU"}
 
  
 
local leapSecTimeStamps = {2272060800, 2287785600, 2303683200, 2335219200, 2366755200, 2398291200, 2429913600, 2461449600, 2492985600, 2524521600, 2571782400, 2603318400, 2634854400, 2698012800, 2776982400, 2840140800, 2871676800, 2918937600, 2950473600, 2982009600, 3029443200, 3076704000, 3124137600, 3345062400, 3439756800, 3550089600, 3644697600, 3692217600}
 
local leapSecTimeStamps = {2272060800, 2287785600, 2303683200, 2335219200, 2366755200, 2398291200, 2429913600, 2461449600, 2492985600, 2524521600, 2571782400, 2603318400, 2634854400, 2698012800, 2776982400, 2840140800, 2871676800, 2918937600, 2950473600, 2982009600, 3029443200, 3076704000, 3124137600, 3345062400, 3439756800, 3550089600, 3644697600, 3692217600}
Line 197: Line 197:
 
   return os.date("*t",surfaceTimestamp)
 
   return os.date("*t",surfaceTimestamp)
 
end
 
end
 
-- ========Parse Functions========
 
 
-- Much of this code derived from https://help.interfaceware.com/code/details/dateparse-lua
 
 
-- Create index table for vailee
 
if true then
 
  local function index_by_name(array)
 
      local dict = {}
 
      for i,name in pairs(array) do
 
        name = name:lower()
 
        dict[name] = i - 1
 
      end
 
      return dict
 
  end
 
  vailee_by_name = index_by_name(vaileetee)
 
end
 
 
-- Given string s, return name of vailee
 
local function lookup_vailee(s)
 
  local vailee = vailee_by_name[s:lower()]
 
  if not vailee then error('expected vailee, got "'..s..'"') end
 
  return vailee
 
end
 
 
local function fix_hahr(BE,DE)
 
  return function(s,d)
 
            if s:upper() == BE then
 
                d.hahr = - math.abs(d.hahr)
 
            elseif s:upper() == DE then
 
                d.hahr = math.abs(d.hahr)
 
            else
 
                error('expected '..BE..' or '..DE..', got "'..s..'"')
 
            end
 
          end
 
end
 
 
--Just returns a number (serves as 'default' for function table)
 
local function parseint(s)
 
  return tonumber(s)
 
end
 
 
-- Possible codes in Dni format string, with associated patterns and functions.
 
-- The default function is parseint(), since most values are just integers, exactly
 
-- as we need them.
 
local fmt_details = {
 
  hhhh = { '%d%d%d%d', 'hahr' };
 
  v    = { '%d+',    'vailee' };
 
  vv  = { '%d%d',  'vailee' };
 
  vvvv = { '%a+', 'vailee', lookup_vailee };
 
  y    = { '%d+',  'yahr' };
 
  yy  = { '%d%d', 'yahr' };
 
  g    = { '%d+',  'gahrtahvo' };
 
  gg  = { '%d%d', 'gahrtahvo' };
 
  t    = { '%d+',  'tahvo' };
 
  tt  = { '%d%d', 'tahvo' };
 
  r    = { '%d+',  'gorahn' };
 
  rr  = { '%d%d', 'gorahn' };
 
  p    = { '%d+',  'prorahn' };
 
  pp  = { '%d%d', 'prorahn' };
 
  xx  = { '%a%a', 'BE or DE', fix_hahr('BE','DE') };
 
  [' '] = { '%s*', 'whitespace' }; -- Allow omission.
 
  [','] = { '%s*,?', 'a comma' };  -- Allow omission and leading whitespace.
 
  w    = { '%a+', 'a word' };    -- Value ignored.
 
  n    = { '%d+', 'a number' };  -- Value ignored.
 
}
 
 
-- Splits one part of a format string off; returns that and the rest.
 
local function split_fmt(fmt)
 
  local c = fmt:match('^(%a)')
 
  if c then
 
      return fmt:match('^('..c..'+)(.*)')
 
  elseif #fmt > 0 then
 
      return fmt:sub(1,1), fmt:sub(2)
 
  end
 
end
 
 
 
local function parseDniDateStr(s, fmt)
 
-- Parses the string, s, according to the format, fmt.
 
 
  fmt = fmt or "hhhh vvvv y g:t:r:p"
 
 
  local matched, d = '', {hahr=1,yahr=1,vailee=0,gahrtahvo=0,tahvo=0,gorahn=0,prorahn=0} --Sets default
 
  local function fail(what, pattern) --Error msg function
 
      if pattern then what = what..' ('..pattern..')' end
 
      if matched ~= '' then what = what..' after "'..matched..'"' end
 
      error('expected '..what..', got "'..s..'"')
 
  end
 
  while fmt ~= '' do
 
      local head_fmt, rest_fmt = split_fmt(fmt)
 
      local pattern, field, fun = unpack(fmt_details[head_fmt] or {})
 
      local part, rest
 
      if pattern then
 
        part, rest = s:match('^('..pattern..')(.*)')
 
        if not part then fail(field,head_fmt) end
 
        d[field] = (fun or parseint)(part,d)
 
        matched = matched .. part
 
      elseif head_fmt:find('^%a') then
 
        error('unknown date/time pattern: '..head_fmt)
 
      elseif s:sub(1,#head_fmt) ~= head_fmt then
 
        fail('"'..head_fmt..'"')
 
      else
 
        matched = matched .. s:sub(1,#head_fmt)
 
        rest = s:sub(#head_fmt + 1)
 
      end
 
      s, fmt = rest, rest_fmt
 
  end
 
  if s ~= '' then fail('nothing') end
 
  return d
 
end
 
 
 
-- ==========Display Functions=========
 
 
local function getVaileeName(vailee, useDniFont)
 
-- Return name of vailee given number (zero-indexed)
 
-- If useDniFont is true, return it in Dnifont text
 
 
    useDniFont = useDniFont or false
 
 
    if(useDniFont) then
 
      return vaileetee_dnifont[vailee+1]
 
    else
 
      return vaileetee[vailee+1]
 
    end
 
end
 
 
local function displayDniTime(dniTime)
 
-- Return dniTime (table) as string of table
 
 
  return '{'..'hahr = '..dniTime['hahr']..', vailee = '..dniTime['vailee']..', vaileeName = '..getVaileeName(dniTime['vailee'])..', yahr = '..dniTime['yahr']..', gahrtahvo = '..dniTime['gahrtahvo']..', tahvo = '..dniTime['tahvo']..', gorahn = '..dniTime['gorahn']..', prorahn = '..dniTime['prorahn']..'}'
 
 
end
 
 
local function displaySurfaceTime(surface)
 
-- Return surfaceTime (table) as string of table
 
 
  return '{'..'year = '..surface['year']..', month = '..surface['month']..', day = '..surface['day']..', hour = '..surface['hour']..', min = '..surface['min']..', sec = '..surface['sec']..', isdst = '..tostring(surface['isdst'])..'}'
 
end
 
 
local function formatSurfaceTime(surfaceTime,format)
 
 
  format = format or 'c'
 
 
  lang = mw.getContentLanguage()
 
 
  return lang:formatDate(format,"@"..makeSurfaceTimeStamp(surfaceTime))
 
--  return lang:formatDate(format,tostring(surfaceTime['year'])..'-'..tostring(surfaceTime['month'])..'-'..tostring(surfaceTime['day'])..' '..tostring(surfaceTime['hour'])..':'..tostring(surfaceTime['min'])..':'..tostring(surfaceTime['sec']))
 
end
 
 
local function formatDniTime(dniTime,format)
 
-- Given a DniTime (table), returns formatted string.
 
-- format is a string with patterns for parts of the date, like standard dates
 
-- Patterns in capitals padded with zeroes
 
-- HHHH, hhhh = hahr (4-digits, Uppercase includes +/-)
 
-- hh = last two digits of the hahr
 
-- XX = 'era' (BE or DE)
 
-- VVVV = vailee by name
 
-- VV,vv = vailee (1 indexed)
 
-- YY, yy = yahr
 
-- GG, gg = gahrtahvo
 
-- TT, tt = tahvo
 
-- RR, rr = gorahnn
 
-- PP, pp = prorahn
 
 
  format = format or "HHHH XX VVVV yy gg:tt:rr:pp"
 
 
  result = format
 
 
  if (dniTime['hahr'] < 0) then
 
      era = "BE"
 
      sign = "-"
 
  else
 
      era = "DE"
 
      sign = ""
 
  end
 
 
result = string.gsub(result,"%a+", {
 
                              ["dHHHH"] = dnitools._num2dnifont(math.abs(dniTime['hahr']),4),
 
                              ["HHHH"] = string.format("%04d",tostring(math.abs(dniTime['hahr']))),
 
                              ["dhhhh"] = dnitools._num2dnifont(math.abs(dniTime['hahr'])),
 
                              ["hhhh"] = math.abs(dniTime['hahr']),
 
                              ["dhh"] = dnitools._num2dnifont(string.sub(dniTime['hahr'],-2)),
 
                              ["hh"] = string.sub(dniTime['hahr'],-2),
 
                              ["dYY"] = dnitools._num2dnifont(dniTime['yahr'],2),
 
                              ["YY"] = string.format("%02d",tostring(dniTime['yahr'])),
 
                              ["dyy"] = dnitools._num2dnifont(dniTime['yahr']),
 
                              ["yy"] = dniTime['yahr'],
 
                              ["dVVVV"] = getVaileeName(dniTime['vailee'],true),
 
                              ["VVVV"] = getVaileeName(dniTime['vailee']),
 
                              ["VV"] = string.format("%02d",tostring(dniTime['vailee']+1)),
 
                              ["dvv"] = dnitools._num2dnifont(dniTime['vailee'] + 1),
 
                              ["vv"] = dniTime['vailee'] + 1,
 
                              ["GG"] = string.format("%02d",tostring(dniTime['gahrtahvo'])),
 
                              ["dgg"] = dnitools._num2dnifont(dniTime['gahrtahvo']),
 
                              ["gg"] = dniTime['gahrtahvo'],
 
                              ["TT"] = string.format("%02d",tostring(dniTime['tahvo'])),
 
                              ["dtt"] = dnitools._num2dnifont(dniTime['tahvo']),
 
                              ["tt"] = dniTime['tahvo'],
 
                              ["RR"] = string.format("%02d",tostring(dniTime['gorahn'])),
 
                              ["drr"] = dnitools._num2dnifont(dniTime['gorahn']),
 
                              ["rr"] = dniTime['gorahn'],
 
                              ["PP"] = string.format("%02d",tostring(dniTime['prorahn'])),
 
                              ["pp"] = dniTime['prorahn'],
 
                              ["dpp"] = dnitools._num2dnifont(dniTime['prorahn']),
 
                              ["XX"] = era,
 
                              ["X"] = sign,
 
})
 
 
  return result
 
 
end
 
 
  
 
-- =============================================================================
 
-- =============================================================================
Line 435: Line 221:
 
     preprocessSingleArg('datetime')
 
     preprocessSingleArg('datetime')
 
     preprocessSingleArg('format')
 
     preprocessSingleArg('format')
 +
    preprocessSingleArg('input')
 
      
 
      
 
     if args['datetime'] then
 
     if args['datetime'] then
       surfaceTime = require("Module:D'ni Time/surface").parseSurfaceDateStr(args['datetime'])
+
       surfaceTime = surfacefunc.parseSurfaceDateStr(args['datetime'],args['input'])
       output = formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surfaceTime)),args['format'])
+
       output = dnifunc.formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surfaceTime)),args['format'])
 
     else  
 
     else  
 
       preprocessSingleArg('year')
 
       preprocessSingleArg('year')
Line 448: Line 235:
  
 
       -- Parse the data parameters
 
       -- Parse the data parameters
       surface = {year = args['year'], month = args['month'], day = args['day'], hour = args['hour'], min = args['minute'], sec = args['second']}
+
       surface = {year = args['year'], month = args['month'] or 1, day = args['day'] or 1, hour = args['hour'] or 0, min = args['minute'] or 0, sec = args['second'] or 0}
  
---      output =  require("Module:D'ni Time/dni").displayDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)),args['format'])
+
---      output =  dnifunc.displayDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)),args['format'])
       output = require("Module:D'ni Time/dni").formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)),args['format'])
+
       output = dnifunc.formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)),args['format'])
 
     end
 
     end
 
     return output
 
     return output
Line 470: Line 257:
  
 
     if args['datetime'] then
 
     if args['datetime'] then
       output = formatSurfaceTime(dni2SurfaceTime(require("Module:D'ni Time/dni").parseDniDateStr(args['datetime'],args['input'])),args['format'])
+
       output = surfacefunc.formatSurfaceTime(dni2SurfaceTime(dnifunc.parseDniDateStr(args['datetime'],args['input'])),args['format'])
 
     else  
 
     else  
 
       preprocessSingleArg('hahr')
 
       preprocessSingleArg('hahr')
Line 483: Line 270:
 
       dni = {hahr = tonumber(args['hahr']), vailee = tonumber(args['vailee']), yahr = tonumber(args['yahr']), gahrtahvo = tonumber(args['gahrtahvo']), tahvo = tonumber(args['tahvo']), gorahn = tonumber(args['gorahn']), prorahn = tonumber(args['prorahn'])}
 
       dni = {hahr = tonumber(args['hahr']), vailee = tonumber(args['vailee']), yahr = tonumber(args['yahr']), gahrtahvo = tonumber(args['gahrtahvo']), tahvo = tonumber(args['tahvo']), gorahn = tonumber(args['gorahn']), prorahn = tonumber(args['prorahn'])}
  
      output = require("Module:D'ni Time/surface").displaySurfaceTime(dni2SurfaceTime(dni),args['format'])
+
--      output = surfacefunc.displaySurfaceTime(dni2SurfaceTime(dni),args['format'])
       output = output.."<br/>"..formatSurfaceTime(dni2SurfaceTime(dni),args['format'])
+
       output = surfacefunc.formatSurfaceTime(dni2SurfaceTime(dni),args['format'])
 
     end
 
     end
 
      
 
      
Line 508: Line 295:
  
 
     output = ""
 
     output = ""
     output = output .. "<br/>"..require("Module:D'ni Time/surface").displaySurfaceTime(surface)
+
     output = output .. "<br/>"..surfacefunc.displaySurfaceTime(surface)
--    output = output .. "<br/>"..require("Module:D'ni Time/dni").displayDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)))
+
--    output = output .. "<br/>"..dnifunc.displayDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)))
--    output = output .. "<br/>"..require("Module:D'ni Time/dni").formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)))
+
--    output = output .. "<br/>"..dnifunc.formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)))
     output = output .. "<br/>"..require("Module:D'ni Time/dni").displayDniTime(dni)
+
     output = output .. "<br/>"..dnifunc.displayDniTime(dni)
     output = output .. "<br/>"..require("Module:D'ni Time/surface").displaySurfaceTime(dni2SurfaceTime(dni))
+
     output = output .. "<br/>"..surfacefunc.displaySurfaceTime(dni2SurfaceTime(dni))
 
     output = output .. "<br/>"..os.date("ghdd",makeSurfaceTimeStamp(surface))
 
     output = output .. "<br/>"..os.date("ghdd",makeSurfaceTimeStamp(surface))
--    output = output .. "<br/>"..formatSurfaceTime(surface,args['format'])
+
--    output = output .. "<br/>"..surfacefunc.formatSurfaceTime(surface,args['format'])
 
--    output = output .. "<br/>"..makeSurfaceTimeStamp(surface)
 
--    output = output .. "<br/>"..makeSurfaceTimeStamp(surface)
 
--    output = output .. "<br/>"..lang:formatDate("c","@"..makeSurfaceTimeStamp(surface))
 
--    output = output .. "<br/>"..lang:formatDate("c","@"..makeSurfaceTimeStamp(surface))

Latest revision as of 04:32, 18 August 2020

Documentation for this module may be created at Module:D'ni Time/doc

-- THIS IS OBVIOUSLY NOT DONE! DO NOT TOUCH! -Vee

dnitools = require("Module:D'ni Tools")
dnifunc = require("Module:D'ni Time/dni")
surfacefunc = require("Module:D'ni Time/surface")

Date = require('Module:Date')._Date

local p = {}

local args = {}
local origArgs
local root

-- Declare important constants
local refDniHahr = 9647
local msPerHahr = 31556925216
local prorahnteePerHahr = 10 * 29 * 5 * 25 * 25 * 25
local msPerProrahn = msPerHahr / prorahnteePerHahr
local refProrahnteePerHahr = 9647 * 290 * 5 * 25 * 25 * 25

local leapSecTimeStamps = {2272060800, 2287785600, 2303683200, 2335219200, 2366755200, 2398291200, 2429913600, 2461449600, 2492985600, 2524521600, 2571782400, 2603318400, 2634854400, 2698012800, 2776982400, 2840140800, 2871676800, 2918937600, 2950473600, 2982009600, 3029443200, 3076704000, 3124137600, 3345062400, 3439756800, 3550089600, 3644697600, 3692217600}
local LeapSecOffset = 10

local function ConvertLeapSecTimeStamps()
-- convert LeapSecTimeStamps from NTP epoch (number of seconds since 1900-01-01 00:00:00)
-- to Unix standard (number of milliseconds since 1970-01-01 00:00:00)

   delta = os.time({year=1900, month=1, day=1, hour=0, min=0})
   for key,value in pairs(leapSecTimeStamps) do
      leapSecTimeStamps[key] = value + delta
   end
end

local function AdjustForLeapSeconds(timestamp)
-- Adjust timestamp for leap seconds
   leapsecs = 0
   for key,value in pairs(leapSecTimeStamps) do
      if timestamp >= value then
         leapsecs = leapsecs + 1
      end
   end
   if leapsecs > 0 then
      leapsecs = leapsecs + (LeapSecOffset - 1)
   end 
   return timestamp + leapsecs
end

local function DejustForLeapSeconds(timestamp)
-- Adjust timestamp for leap seconds the other way
   leapsecs = 0
   for key,value in pairs(leapSecTimeStamps) do
      if timestamp >= value then
         leapsecs = leapsecs + 1
      end
   end
   if leapsecs > 0 then
      leapsecs = leapsecs + (LeapSecOffset - 1)
   end 
   return timestamp - leapsecs
end

local function makeSurfaceTimeStamp(timeStampTable)
-- convert a UTC date-time to a adjusted timestamp
   temp = os.time(timeStampTable)
   return AdjustForLeapSeconds(temp)
end

-- Run conversion of leapseconds and conversion of reference Timestamp here,
-- since these require the above functions to be already declared

ConvertLeapSecTimeStamps()
local refTimeStamp = makeSurfaceTimeStamp({year=1991, month=4, day=21, hour=16, min=54})

local function adjust(dniTime)
-- Ensure DniTime values are within bounds
        while (dniTime['prorahn'] > 25) do
            dniTime['prorahn'] = dniTime['prorahn'] - 25
            dniTime['gorahn'] = dniTime['gorahn'] + 1
        end

        while (dniTime['prorahn'] < 0) do
            dniTime['prorahn'] = dniTime['prorahn'] + 25
            dniTime['gorahn'] = dniTime['gorahn'] - 1
        end

        while (dniTime['gorahn'] > 25) do
            dniTime['gorahn'] = dniTime['gorahn'] - 25;
            dniTime['tahvo'] = dniTime['tahvo'] + 1;
        end

        while (dniTime['gorahn'] < 0) do
            dniTime['gorahn'] = dniTime['gorahn'] + 25
            dniTime['tahvo'] = dniTime['tahvo'] - 1
        end

        while (dniTime['tahvo'] > 25) do
            dniTime['tahvo'] = dniTime['tahvo'] - 25
            dniTime['gahrtahvo'] = dniTime['gahrtahvo'] + 1
        end

        while (dniTime['tahvo'] < 0) do
            dniTime['tahvo'] = dniTime['tahvo'] + 25
            dniTime['gahrtahvo'] = dniTime['gahrtahvo'] - 1
        end

        while (dniTime['gahrtahvo'] > 5) do
            dniTime['gahrtahvo'] = dniTime['gahrtahvo'] - 5
            dniTime['yahr'] = dniTime['yahr'] + 1
        end

        while (dniTime['gahrtahvo'] < 0) do
            dniTime['gahrtahvo'] = dniTime['gahrtahvo'] + 5
            dniTime['yahr'] = dniTime['yahr'] - 1
        end

        while (dniTime['yahr'] > 29) do
            dniTime['yahr'] = dniTime['yahr'] - 29
            dniTime['vailee'] = dniTime['vailee'] + 1
        end

        while (dniTime['yahr'] < 0) do
            dniTime['yahr'] = dniTime['yahr'] + 29
            dniTime['vailee'] = dniTime['vailee'] - 1
        end

        while (dniTime['vailee'] > 9) do
            dniTime['vailee'] = dniTime['vailee'] - 10
            dniTime['hahr'] = dniTime['hahr'] + 1;
        end

        while (dniTime['vailee'] < 0) do
            dniTime['vailee'] = dniTime['vailee'] + 10
            dniTime['hahr'] = dniTime['hahr'] - 1
        end

        return dniTime
end


local function surface2DniTime(surfaceTimeStamp)
-- Given a surfaceTimestamp
-- Return a DniTime (table)
   surface = surface or refTimeStamp

   dniTime = {}

   delta = (surfaceTimeStamp - refTimeStamp) * 1000

   dniTime['hahr'] = math.floor(delta / msPerHahr)

   delta = delta - (dniTime['hahr'] * msPerHahr)

   delta = delta * (prorahnteePerHahr / msPerHahr)

   dniTime['vailee'] = math.floor(delta / (29 * 5 * 25 * 25 * 25))
   delta = delta - (dniTime['vailee'] * (29 * 5 * 25 * 25 * 25))

   dniTime['yahr'] = math.floor(delta / (5 * 25 * 25 * 25))
   delta = delta - (dniTime['yahr'] * (5 * 25 * 25 * 25))

   dniTime['gahrtahvo'] = math.floor(delta / (25 * 25 * 25))
   delta = delta - (dniTime['gahrtahvo'] * (25 * 25 * 25))

   dniTime['tahvo'] = math.floor(delta / (25 * 25))
   delta = delta - (dniTime['tahvo'] * (25 * 25))

   dniTime['gorahn'] = math.floor(delta / 25)
   delta = delta - (dniTime['gorahn'] * 25)

   dniTime['prorahn'] = math.floor(delta)

   dniTime['hahr'] = dniTime['hahr'] + refDniHahr
   dniTime['yahr'] = dniTime['yahr'] + 1

   --return adjust(dniTime)
   return dniTime
end

local function dni2SurfaceTime(dniTime)
-- Given a DniTime (table)
-- Return a surfacteTimestamp
   dniTime = dniTime or {hahr = refDniHahr, vailee = 0, yahr = 1, gahrtahvo = 0, tahvo = 0, gorahn = 0, prorahn = 0}

   dniTime = adjust(dniTime)

   dTimeInProrahntee = dniTime['prorahn'] + (dniTime['gorahn'] * 25) + (dniTime['tahvo'] * 25 * 25) + (dniTime['gahrtahvo'] * 25 * 25 * 25) + ((dniTime['yahr'] - 1) * 5 * 25 * 25 * 25) + ((dniTime['vailee']) * 29 * 5 * 25 * 25 * 25) + (dniTime['hahr'] * 290 * 5 * 25 * 25 * 25)

   dTimeDelta = refProrahnteePerHahr - dTimeInProrahntee 
   
   dTimeDelta = dTimeDelta * msPerProrahn

   dTimeDelta = (refTimeStamp * 1000) - dTimeDelta

   surfaceTimestamp = DejustForLeapSeconds(dTimeDelta/1000)

   return os.date("*t",surfaceTimestamp)
end

-- =============================================================================

local function preprocessSingleArg(argName)
    -- If the argument exists and isn't blank, add it to the argument table.
    -- Blank arguments are treated as nil to match the behaviour of ParserFunctions.
    if origArgs[argName] and origArgs[argName] ~= '' then
        args[argName] = origArgs[argName]
    end
end

function p.surface2dni(frame)
    -- If called via #invoke, use the args passed into the invoking template.
    -- Otherwise, for testing purposes, assume args are being passed directly in.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end

    output = ""
    
    preprocessSingleArg('datetime')
    preprocessSingleArg('format')
    preprocessSingleArg('input')
    
    if args['datetime'] then
       surfaceTime = surfacefunc.parseSurfaceDateStr(args['datetime'],args['input'])
       output = dnifunc.formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surfaceTime)),args['format'])
    else 
       preprocessSingleArg('year')
       preprocessSingleArg('month')  
       preprocessSingleArg('day') 
       preprocessSingleArg('hour') 
       preprocessSingleArg('minute') 
       preprocessSingleArg('second') 

       -- Parse the data parameters
       surface = {year = args['year'], month = args['month'] or 1, day = args['day'] or 1, hour = args['hour'] or 0, min = args['minute'] or 0, sec = args['second'] or 0}

---      output =  dnifunc.displayDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)),args['format'])
      output = dnifunc.formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)),args['format'])
     end
     return output
end

function p.dni2surface(frame)
    -- If called via #invoke, use the args passed into the invoking template.
    -- Otherwise, for testing purposes, assume args are being passed directly in.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end

    preprocessSingleArg('datetime')
    preprocessSingleArg('format')
    preprocessSingleArg('input')

    if args['datetime'] then
       output = surfacefunc.formatSurfaceTime(dni2SurfaceTime(dnifunc.parseDniDateStr(args['datetime'],args['input'])),args['format'])
    else 
      preprocessSingleArg('hahr')
      preprocessSingleArg('vailee')  
      preprocessSingleArg('yahr') 
      preprocessSingleArg('gahrtahvo') 
      preprocessSingleArg('tahvo') 
      preprocessSingleArg('gorahn')
      preprocessSingleArg('prorahn') 

      -- Parse the data parameters
      dni = {hahr = tonumber(args['hahr']), vailee = tonumber(args['vailee']), yahr = tonumber(args['yahr']), gahrtahvo = tonumber(args['gahrtahvo']), tahvo = tonumber(args['tahvo']), gorahn = tonumber(args['gorahn']), prorahn = tonumber(args['prorahn'])}

--      output = surfacefunc.displaySurfaceTime(dni2SurfaceTime(dni),args['format'])
      output = surfacefunc.formatSurfaceTime(dni2SurfaceTime(dni),args['format'])
    end
    
    return output

end

function p.test(frame)
    -- If called via #invoke, use the args passed into the invoking template.
    -- Otherwise, for testing purposes, assume args are being passed directly in.
    if frame == mw.getCurrentFrame() then
        origArgs = frame:getParent().args
    else
        origArgs = frame
    end
    
    -- Parse the data parameters
    
    lang = mw.getContentLanguage()

    surface = {year = -7658, month = 5, day = 31, hour = 6, min = 56, sec = 58, isdst = true}
    dni = {hahr = -1, vailee = 1, yahr = 1, gahrtahvo = 1, tahvo = 1, gorahn = 1, prorahn = 1}

    output = ""
    output = output .. "<br/>"..surfacefunc.displaySurfaceTime(surface)
--    output = output .. "<br/>"..dnifunc.displayDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)))
--    output = output .. "<br/>"..dnifunc.formatDniTime(surface2DniTime(makeSurfaceTimeStamp(surface)))
    output = output .. "<br/>"..dnifunc.displayDniTime(dni)
    output = output .. "<br/>"..surfacefunc.displaySurfaceTime(dni2SurfaceTime(dni))
    output = output .. "<br/>"..os.date("ghdd",makeSurfaceTimeStamp(surface))
--    output = output .. "<br/>"..surfacefunc.formatSurfaceTime(surface,args['format'])
--    output = output .. "<br/>"..makeSurfaceTimeStamp(surface)
--    output = output .. "<br/>"..lang:formatDate("c","@"..makeSurfaceTimeStamp(surface))


    return output
end

return p