I want to be able to use tick() or os.time() to get the current date and time. How would I do so?
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)
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())