Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by
Validark 1580 Snack Break Moderation Voter
8 years ago

I want to be able to use tick() or os.time() to get the current date and time. How would I do so?

0
(here is a module I wrote that solves this problem: http://www.roblox.com/Date-Module-item?id=271818993 ) BlueTaslem 18071 — 8y

3 answers

Log in to vote
10
Answered by 8 years ago

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)
1
+1 for an ok answer DreadPirateRobux 655 — 8y
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? M39a9am3R 3210 — 8y
0
Is there a way to tell AM or PM using these functions? AzrefriskDreemurr 8 — 3y
Ad
Log in to vote
0
Answered by 4 years ago

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

Log in to vote
-3
Answered by
Validark 1580 Snack Break Moderation Voter
8 years ago

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())
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. Validark 1580 — 8y
2
....better? how is this better? User#11893 186 — 8y
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 Validark 1580 — 8y
0
Uh... no? User#11893 186 — 8y
1
What's wrong with it? Validark 1580 — 8y

Answer this question