local Y,Q=math.floor,math.ceil local function c(Y)return Y%4==0 and(Y%25~=0 or Y%16==0)end local function T(Q)return(Y(Q/4)-Y(Q/100))+Y(Q/400)end local function M(Y)return 365*Y+T(Y)end local function B(Y)return 365*Y+T(Y-1)end local function e(Y,Q)for c=1,#Y,1 do if Q-Y[c]<=0 then return c,Q end Q=Q-Y[c]end end local function x(T)local x=T or tick()local p=Q((x+1)/86400)+M(1970)local C=400*Y(p/M(400))local E=100*Y((p%M(400))/M(100))local t=4*Y(((p%M(400))%M(100))/M(4))local s,f s,p=e({366,365;365,365},p-B((t+E)+C))s=s-1 local H=((s+t)+E)+C f,p=e({31;c(H)and 29 or 28,31;30,31,30,31;31,30,31;30;31},p)return H,f,p end local function p(Q)local c=Y((Q/3600)%24)local T=Y((Q/60)%60)local M=Y(Q%60)return c,T,M end return{Date=x;Time=p}


local floor, ceil = math.floor, math.ceil

local function isLeapYear(year)
    return year % 4 == 0 and (year % 25 ~= 0 or year % 16 == 0)
end

local function GetLeaps(year)
	return floor(year/4) - floor(year/100) + floor(year/400)
end

local function CountDays(year)
	return 365*year + GetLeaps(year)
end

local function CountDays2(year)
	return 365*year + GetLeaps(year - 1)	
end

local function overflow(array, seed)
	for i = 1, #array do
		if seed - array[i] <= 0 then
			return i, seed
		end
		seed = seed - array[i]
	end
end

local function GetYMDFromSeconds(seconds)
	local seconds = seconds or tick()
    local days = ceil((seconds + 1) / 86400) + CountDays(1970)
    
    local _400Years = 400*floor(days / CountDays(400))
    local _100Years = 100*floor(days % CountDays(400) / CountDays(100))
    local _4Years = 4*floor(days % CountDays(400) % CountDays(100) / CountDays(4))
    
    local _1Years, month
    _1Years, days = overflow({366,365,365,365}, days - CountDays2(_4Years + _100Years + _400Years))
	_1Years	= _1Years - 1
    
    local year = _1Years + _4Years + _100Years + _400Years
    month, days = overflow({31,isLeapYear(year) and 29 or 28,31,30,31,30,31,31,30,31,30,31}, days)
        
	return year, month, days
end

local function GetTimeFromSeconds(seconds)
	local hours	= floor(seconds / 3600 % 24)
	local minutes	= floor(seconds / 60 % 60)
	local seconds	= floor(seconds % 60)
	
	return hours, minutes, seconds
end

return {Date = GetYMDFromSeconds, Time = GetTimeFromSeconds}
