[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Badly formatted os.date format crashes
- From: Klaus Ripke <paul-lua@...>
- Date: Tue, 9 Sep 2008 14:42:14 +0200
hi
On Tue, Sep 09, 2008 at 09:14:10AM -0300, Roberto Ierusalimschy wrote:
> Lua 5.2 has this layer. According to ISO C, "If a conversion specifier
> is not one of the above,the behavior is undefined", and undefined
> behavior includes crashing. It is a really stupid behavior, but it is
> "legally correct"
... or just roll your own.
We had to, because we use dietlibc, where gmtime - and thus strftime -
is completely broken for dates < 1970.
Between 1901 and 2099, and consequently for all dates representable
in the usual 32 bit integer, gmtime and timegm are not as hard
as one might think.
Find a little pure Lua version attached.
The "gmtime" replacement YmdHMS is tested for all integer values.
You might want to accomodate for the timezone.
cheers
-- date utilities
local tonumber, floor = tonumber, math.floor
module 'date'
-- for timegm/gmtime
mondays = {0,31,59,90,120,151,181,212,243,273,304,334}
mondays4 = {0,31,60,91,121,152,182,213,244,274,305,335}
-- timegm with year incl. century, month 1-based
function timegm (Y, m, d, H, M, S)
Y = Y - 1970
return 3600*(H or 0) + 60*(M or 0) + (S or 0) + 86400*
(Y*365 + floor((12*Y+m+21)/48) +mondays[tonumber(m)] + (d or 1)-1)
end
function YmdHMS (t) -- basically gmtime
local day = floor(t/86400)+365
-- 1.1.69 is -365 days. from there every year gives 365.25 days
local y69 = floor((day+.75)/365.25)
local yday = day - floor(y69*365.25)
if yday < 0 then yday = 0 end -- OOPS
local mon = 12
local mdays = 0==(y69+1)%4 and mondays4 or mondays
while yday < mdays[mon] do mon=mon-1 end
local d = 1 + yday - mdays[mon]
local m = mon
local Y = 1969 + y69
t = t%86400
local S = t % 60
t = (t - S)/60
local M = t % 60
local H = (t - M)/60
return Y,m,d,H,M,S
end