Custom date and time solution in JS

Viewed 70

I have this bit of lua code

<script src="https://github.com/fengari-lua/fengari-web/releases/download/v0.1.0/fengari-web.js"></script>

<div>The local time in Ixnay is <span id="IxTime"></span></div>
<script type="application/lua">
local epoch = os.time{year=2014,day=1,month=1}
-- equation: x + y = 2016*365+182; x + z = 2024*365; z = y * 4
-- this assumes 4x rate past normal time
-- attempts to use 3x rate could not provide accurate results following timestamps

function conv(t)
  local time = os.time(t)
  local seconds_since_epoch = time - epoch
  return seconds_since_epoch * 4 + epoch
end

js.global.document:querySelector("#IxTime").innerHTML = os.date(" %Y-%m-%d %H:%M:%S", conv(os.date('*t', os.time())))

</script>

Because of the limitations of lua, the Y2k38 bug prevents the time from going past 2038 before breaking. I don't know a lot about javascript but I know it has a more robust date/time mechanic. I've tinkered around with it for a bit but I'm running into two main problems:

  1. I cannot figure out how to create the faster rate of time (time should move roughly 4x faster than IRL)

  2. I can't seem to make the time start from my designated epoch time of 01/01/2014

any help would be great!

1 Answers

The problem does not exist in Lua built with usual 64-bit integers under 64-bit OS.
The problem is: integers in Fengari are 32-bit, and os.date() accepts integer time, hence 2k38 limit.

Workaround: shift the time by 4*N years to make it below 2038.

<script src="https://github.com/fengari-lua/fengari-web/releases/download/v0.1.4/fengari-web.js"></script>

<div>The local time in Ixnay: <span id="IxTime"></span></div>
<script type="application/lua">
local epoch = os.time{year=2014,day=1,month=1}

function conv(t)
  local time = os.time(t)
  local seconds_since_epoch = time - epoch
  return seconds_since_epoch * 4.0 + epoch
end

local four_years = os.time{year=2024,day=1,month=1} 
                 - os.time{year=2020,day=1,month=1}

local function time_to_string(seconds_since_epoch)
   local k = math.max(0, math.ceil((seconds_since_epoch - math.maxinteger) / four_years))
   local s = seconds_since_epoch - k * four_years
   return os.date(" %%s-%m-%d %H:%M:%S", s):format(tostring(tonumber(os.date("%Y", s)) + 4*k))
end

js.global.document:querySelector("#IxTime").innerHTML = time_to_string(conv(os.date('*t')))

</script>

Related