lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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