2017-09-27 39 views
2

由于2038年问题(https://en.wikipedia.org/wiki/Year_2038_problem),在32位机器上调用os.time({year = 2039,month = 1,day = 1,hour = 0,sec = 1})后,我们得到零。如何使它在lua层兼容,并获得像运行在64位机器上的结果? 是否可以编写如下的函数?否则,如何实现它?如何在Lua 5.1的32位机器上使os.time()兼容?

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()?

+0

将年份向下移动'4 * N'并且在结果中添加'N *秒数'到结果 –

+0

好主意!还有一个问题,就是闰年。 “除了可以被100整除的年份以外,每年可以被四整除的年份是闰年,但是如果它们可以被400整除,这些百年闰年就是闰年。例如,1700年,1800年和1900年不是闰年,而是1600年和2000年。“ – youzhiwan

+0

@ youzhiwan - 在1970-2038年范围内,所有可以被4整除的年份都是闰年。 –

回答

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? 
+0

非常感谢您提供完整的代码!但是我发现它有什么问题。我把你的代码的结果与一些工具比如“https://rimzy.net/tools/php_timestamp_converter.php”比较,你的代码在年份<2100时是正确的,而当它是错误的时候年> = 2100,月> 2。正如我所说的,我们认为“除了可以整除100年的年份”之外。我找不到一个简单的方法来实现它。 – youzhiwan

+0

因为2100不是闰年,而且您的代码已将其视为闰年。 – youzhiwan

+0

@ youzhiwan - 答案更新。请从1970年开始测试所有可能的日期。 –

相关问题