How do I get the Hour and Minute using os.date?

Currently I’m building a showcase and thought it’d be neat to have a clock that shows the user’s local time…But I’m not quite sure how I’d get the hour.

Why do I need only the hour you might ask? Well. I want to adjust the time depending on if it’s in the AM or PM. I use 24 hour time personally, but I know not everyone does so I’d like to check if the time is after 12PM, if so, it subtracts 12 from the time to get the time in PM.

If anyone can help me, that’d be much appreciated.

I’m using this in a SurfaceGui.

Code:

--ServerScript
local TimeLabel = script.Parent

function localTime(date)
    local dateString = "{hour}:{min}"
    local result = string.gsub(dateString, "{(%w+)}", date)
    return result
end

while wait(1) do
local now = os.time()
TimeLabel.Text = localTime(os.date("*t", now))
end

–I Modified Tiffblocks’ code linked below:

9 Likes

What do you mean?

I need the local time (hour and minute separate)…

Whats wrong with just using the dictionary values

local hours = os.date("*t",now)["hour"]

local mins = os.date("*t",now)["min"]
6 Likes

How to convert to 12H format:

local function to12H(hour)
    hour = hour % 24
    return (hour - 1) % 12 + 1 .. (hour > 11 and "PM" or "AM")
end

How to use it to format the current time:

local function getTime()
    local date = os.date("!t")
    return ("%02d:%02d %s"):format(((date.hour % 24) - 1) % 12 + 1, date.min, date.hour > 11 and "PM" or "AM")
end
print(getTime()) --> 09:53 PM
6 Likes

Nothing at all. :joy:

This is my first time using os.date, and I looked on the wiki for something like that…But didn’t find anything. I’ll try that right now. :slight_smile:

Use this, in a local script:


-- localscript, local time, local script
local TimeLabel = script.Parent
local date = os.date("*t")

function getTime()
    local hour = tonumber(date["hour"])
    local minute = date["min"]
    if hour > 12 then
         hour = hour - 12
    end
    return(tostring(hour) .. ":" .. minute)
end

while wait(1) do
    local now = os.time()
    TimeLabel.Text = getTime()
end

edit: whoops, fixed typo

3 Likes

@FieryEvent I don’t understand at all what you’re doing…

@Fusbot and @VineyardVine I modified and came up with this

local TimeLabel = script.Parent
local AMIndicator = script.Parent.Parent.AMIndicator
local AM = true

local function updateTime()
    while wait(1) do
        local now = os.time()
        local Hours = os.date("*t",now)["hour"]
        local Mins = os.date("*t",now)["min"]

        if Hours > 12 then
    	    Hours = Hours - 12
    	    AM = false
	        AMIndicator.Text = "PM"
        else
	        AM = true
	        AMIndicator.Text = "AM"
        end
    
        TimeLabel.Text = Hours .. ":" .. Mins
    end
end
updateTime()

But if the minute is below 10, it shows as the number (7, instead of 07). Is that just something that happens with os.date by itself or is it something I’m doing wrong?

I can easily add code to account for that but I just don’t fully understand why it’s doing it.

And if you have any tips to improve my code that’d be helpful. :slight_smile:

1 Like
local function to12H(hour)
    hour = hour % 24
    return (hour - 1) % 12 + 1
end

local function getTime()
    local date = os.date("*t")
    return ("%02d:%02d"):format(((date.hour % 24) - 1) % 12 + 1, date.min)
end

local AMIndicator = script.Parent.Parent.AMIndicator
local TimeLabel = script.Parent

while wait(1) do
	local currentHour = os.date("*t")["hour"]
	if currentHour < 12 or currentHour == 24 then
		AMIndicator.Text = 'AM'
	else
		AMIndicator.Text = 'PM'
	end
	TimeLabel.Text = getTime()
end

It’s just the way numbers are stored. 7 is shorter than 07, so why store it as 07? This code will fix your problem. Tell me if that doesn’t work.

18 Likes

Whoops I guess my solution was premature.

I tested it in game and all it returned was the UTC time instead of my local time. :confused:

Is that a local script or server script? If you want local time, it needs to be a local script.

Also, instead of os.date(“*t”,now) just do os.date(“*t”) that could be the issue.

It’s a ServerScript inside of a SurfaceGui.

I’ll switch to local and see what happens

You can’t have local time if you have it in the server, as the server is not local. When you said local time, I assumed you meant that you want the clock to display the local time for each player. If you want it to display YOUR local time for EVERYONE then that can be done too, but some math would have to be done to the hour to make it line up with you. If it doesn’t matter that it’s YOUR time zone, and you just want it to be local for everyone, move the SurfaceGui into StarterGui, change the script to a LocalScript, and use the Adornee property of the SurfaceGui to select the part you want it displayed on.

1 Like

That was my issue. Thanks!

I believe tick() returns the local timestamp if run on the client, as opposed to os.time(), which returns the GMT timestamp.

2 Likes

os.date("*t") returns the components of the current (local time if called on a localscript) in a table, such as hour and min.

Field Type Description
hour int An integer between 1 and 24 describing the current hour of the day.
min int An integer between 0 and 59 describing the current minute of the hour.

Because the hour is in 1-24 range instead of 0-23, we get the remainder of hour in 24 hours hour % 24, so that when hour is 24, 24 % 24 = 0. This allows us to show AM instead of PM at midnight, because 0 < 12.

% is used in lua to get the remainder.

In the 12 hour system, we want to show “12:00 PM”, instead of “00:00 AM”, we need to account to not show “00:00” and to not show “AM” when it’s midday. To do that:

  • Since hour % 12 (which is in 0-11 range) gives us 0 when hour is 0 or 12, we need to shift it so it gives us 12, hence: (hour - 1) % 12 + 1 (which is 1-12 range).

  • Since midday is included in PM, any hour after 11 AM is PM, in other words, any hour being 12 or higher is PM, hence:
    hour > 11 and "PM" or "AM". This expression will return “PM” if the hour is bigger than 11 otherwise “AM”.

Now to input the hour and min in the HH:MM AM/PM format we use string.format (printf):

"%02d:%02d %s"

%02d is a format specifier (%[flags][width][.precision][length]specifier ) which uses:

flags description
0 Left-pads the number with zeroes (0) instead of spaces when padding is specified (see width sub-specifier).
so: 1:0 PM turns to 01:00 PM
width description
(number) Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.
which is: 2
specifier Output Example
d or i Signed decimal integer 392
which is: d

%s is a format specifier which uses:

specifier Output Example
s String of characters sample
10 Likes

That was much more detailed than I was expecting.

But that helps me understand it a lot better!! Thanks!

1 Like

You really should look into it as Fusbot’s solution doesn’t handle midday and midnight correctly.

I’ll look into it later today when I have time. Thank you again!

I edited my solution to use FieryEvents formatting, whilst still working for your use case.

2 Likes