2017-09-27 3 views
2

Als Ergebnis des Jahr-2038-Problems (https://en.wikipedia.org/wiki/Year_2038_problem) erhalten wir nach Aufruf von os.time ({Jahr = 2039, Monat = 1, Tag = 1, Stunde = 0, Sekunde = 1}) auf einer 32-Bit-Maschine keine Antwort. Wie kann man es in der Lua-Ebene kompatibel machen und Ergebnisse erhalten, wie auf einer 64-Bit-Maschine zu laufen? Ist es möglich, eine Funktion wie die folgende zu schreiben? Ansonsten, wie erreiche ich das?Wie macht man os.time() Kompatibilität auf einer 32bit Maschine in Lua 5.1?

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 

Wie schreibe ich calculateDeltaTime()?

+0

Umschalttaste das Jahr mit einem Minus von 'N' 4 * und als Add' N * Anzahl der Sekunden in 4 Jahren 'zu dem Ergebnis –

+0

Gute Idee! Und es gibt ein Problem, etwa Schaltjahr. "Jedes Jahr, das genau durch vier teilbar ist, ist ein Schaltjahr, ausgenommen Jahre, die genau durch 100 teilbar sind, aber diese Jahrhundertjahre sind Schaltjahre, wenn sie genau durch 400 teilbar sind. Zum Beispiel die Jahre 1700, 1800 und 1900 waren keine Schaltjahre, aber die Jahre 1600 und 2000 waren. " – youzhiwan

+0

@youzhiwan - Im Bereich 1970-2038 sind alle durch 4 teilbaren Jahre Schaltjahre. –

Antwort

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

Vielen Dank für Ihren vollständigen Code! Aber ich habe etwas falsch damit gefunden. Ich habe das Ergebnis Ihres Codes mit einem Tool wie "https://rimzy.net/tools/php_timestamp_converter.php" vergleichen können, Ihr Code ist richtig, wenn Jahr <2100, während es falsch ist, wenn Jahr> = 2100, Monat> 2. Wie gesagt, denken wir an "außer für Jahre, die genau durch 100 teilbar sind". Ich kann keinen einfachen Weg finden, es zu realisieren. – youzhiwan

+0

Weil 2100 kein Schaltjahr ist und Ihr Code es als Schaltjahr betrachtet hat. – youzhiwan

+0

@youzhiwan - Antwort aktualisiert. Bitte testen Sie es für alle möglichen Daten ab 1970. –

Verwandte Themen