2

由于 2038 年问题(<a href="https://en.wikipedia.org/wiki/Year_2038_problem" rel="nofollow noreferrer">https://en.wikipedia.org/wiki/Year_2038_problem),我们在 32 位机器上调用 os.time({year=2039, month=1, day=1, hour=0, sec=1}) 后得到 nil。如何使其在 lua 层兼容,并得到类似的结果在 64 位机器上运行?编写如下函数是否可行?否则怎么实现呢?

local function time32Compatibility(timeTable)
    local kMaxYearIn32Bit = 2037;
    if timeTable and timeTable.year and timeTable.year >= kMaxYearIn32Bit then
        local originalTable = clone(timeTable);
        timeTable.year = kMaxYearIn32Bit;
        local deltaTime = calculateDeltaTime(timeTable,originalTable)
        return os.time(timeTable) + kMaxYearIn32Bit*;
    else
        return os.time(timeTable);
    end
end

如何编写calculateDeltaTime()?

4

1 回答 1

3
local orig_os_time = os.time

function os.time(timeTable)
   if timeTable then
      -- assume that all years divisible by 4 are leap years
      local four_year_ctr = math.floor((timeTable.year - 2000) / 4)
      timeTable.year = timeTable.year - four_year_ctr * 4
      local result = orig_os_time(timeTable) + four_year_ctr * ((365*4+1)*24*60*60)
      timeTable.year = timeTable.year + four_year_ctr * 4
      -- make a correction for non-leap years 2100,2200,2300, 2500,2600,2700,...
      -- subtract ("March 1, 2000" - 12 hours) and divide by 100 "wrong" years
      -- It should work for all time zones from UTC-1200 to UTC+1200
      local centuries = math.floor((result - (951868800 - 12*60*60)) / (25*(365*4+1)*24*60*60))
      local wrong_feb29_ctr = math.floor((centuries * 6 + 7) / 8)
      return result - wrong_feb29_ctr * (24*60*60)
   else
      return orig_os_time()
   end
end

-- Example:
print(os.time{year = 1002017, month = 9, day = 27, hour = 0, min = 0, sec = 0})
-- Will Lua be alive after million years?
-- Will 32-bit Linux systems be alive after 2038?
于 2017-09-27T07:48:10.603 回答