Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do you get the Date and time from Unix Epoch time?

3 answers

✓ Accepted answer

In normal Lua (non-ROBLOX), this can be accomplished by using the os.date function. Unfortunately, this function doesn't exist in ROBLOX.

However, it is possible to calculate the date and time purely with mathematical operations, based off of the number returned by os.time. It's important to use os.time instead of tick, because tick returns a number that's affected by the server's timezone, which is undesired behavior. os.time, on the other hand, always returns the correct(ish) Unix Timestamp.

This function I've written below can give you the current year, month, day, hours, minutes, and seconds. The code for calculating the time isn't that hard to understand, but the date code is a mess due to leap years being thrown in. I'm not going to explain the code that creates the date because it's really complicated and you probably don't care anyways, but just know that it works.

The code to generate the time works by simply dividing the current timestamp out and finding a remainder. For example, to find the minutes, all you have to do is divide the current timestamp by 60 (hours) and then find the remainder of dividing by 60 again (for minutes) which will be the current number of minutes on the clock.

The CurrentDate function shouldn't be called manually, it's just to be used internally by the CurrentTime function, which takes one parameter (hoursOffset), which is the number of hours to offsite the time by. This allows you to change the time based on the timezone that you live in. In my code, I'm using -7, but you can adjust this to receive your desired timezone, or omit it for UTC.

The function returns a table with the following keys: year, month, day, hours, minutes, seconds.

minutes and seconds will be strings if they are less than 10, this is so that a zero can be added to the beginning so that they are stylized correctly. Otherwise, the values will be numbers.

I included an example at the bottom to print out the current date and time. I hope this answers your question.


function CurrentDate(z)
	local z = math.floor(z / 86400) + 719468
	local era = math.floor(z / 146097)
	local doe = math.floor(z - era * 146097)
	local yoe = math.floor((doe - doe / 1460 + doe / 36524 - doe / 146096) / 365)
	local y = math.floor(yoe + era * 400)
	local doy = doe - math.floor((365 * yoe + yoe / 4 - yoe / 100))
	local mp = math.floor((5 * doy + 2) / 153)
	local d = math.ceil(doy - (153 * mp + 2) / 5 + 1)
	local m = math.floor(mp + (mp < 10 and 3 or -9))
	return y + (m <= 2 and 1 or 0), m, d
end

function CurrentTime(hoursOffset)
	local unixTime = math.floor(os.time()) - (60*60*(hoursOffset or 0))
	
	local hours = math.floor(unixTime / 3600 % 12)
	local minutes = math.floor(unixTime / 60 % 60)
	local seconds = math.floor(unixTime % 60)

	local year, month, day = CurrentDate(unixTime)
	
	return {
		year = year,
		month = month, 
		day = day,
		hours = hours,
		minutes = minutes < 10 and "0" .. minutes or minutes,
		seconds = seconds < 10 and "0" .. seconds or seconds
	}
end

local date = CurrentTime(-7)

print(date.month .. "/" .. date.day .. "/" .. date.year .. " " .. date.hours .. ":" .. date.minutes .. ":" .. date.seconds)

3 comments

1

+1 for an ok answer

1

ROBLOX really needs to add a os.date() function. I know there is a way to mess around with os.time but use {} to set dates and times to get a specific output. Maybe try experimenting with that?

0

Is there a way to tell AM or PM using these functions?

Hello from 2020! Why not just using something like print( os.date( '!%c' ) )?

I figured out a better alternative, that actually will always be accurate:

local getDate = function(unix)
	-- Given unix date, return string date
	local tabIndexOverflow = function(seed, table)
		for i = 1, #table do
			if seed - table[i] <= 0 then
				return i, seed
			end
			seed = seed - table[i]
		end
	end
	local unix =  unix or os.time()

	local dayCount = function(yr) return (yr % 4 == 0 and (yr % 100 ~= 0 or yr % 400 == 0)) and 366 or 365 end
	local year, days, month = 1970, math.ceil(unix/86400)
	while days >= dayCount(year) do days = days - dayCount(year) year = year + 1 end -- Calculate year and days into that year

	month, days = tabIndexOverflow(days, {31,(dayCount(year) == 366 and 29 or 28),31,30,31,30,31,31,30,31,30,31}) 

	return string.format("%d/d/d", month, days, year)
end

local getTime = function(seconds)
	local seconds = seconds or os.time()
	local hours = math.floor(seconds / 3600 % 24)
	hours = hours > 12 and hours - 12 or hours == 0 and 12 or hours
	return string.format("d:d:d %s", hours, math.floor(seconds / 60 % 60), math.floor(seconds % 60), hours > 12 and "pm" or "am")
end

print(getDate())
print(getTime())

5 comments

1

Line 19 and 26 are messed up for some reason and I can't fix them? I'd post what it should be, but that gets messed up too :/ If you want to use these functions you will need to edit the string.format yourself.

2

....better? how is this better?

2

It's shorter, simpler, has variables that are obviously named, makes logical sense, is not an impossible-to-interpret algorithm that you hope works most of the time, etc

0

Uh... no?

1

What's wrong with it?

This discussion is preserved as it was. New answers, comments, and votes are closed.