Trying to make a membership system but I dont know how to get how many days are left in the membership

Hello, I am trying to achieve a membership system.

And I want it to display how many days are left in the membership.
I store the Purchase Date in a datastore. And I got the purchase date by calling tick()

How do I display how much time there is left until it expires?

Script:

local Player = game.Players.LocalPlayer


wait(1)
if Player.Data.PurchaseDate.Value == 0 then
	script.Parent.Text = "0 Days"
else
	local subtracted = 30 - Player.Data.PurchaseDate.Value
	print(os.date("*t", subtracted).day)
	
end
Player.Data.PurchaseDate.Changed:Connect(function()
	if Player.Data.PurchaseDate.Value ~= 0 then
		script.Parent.Text = tick() - Player.Data.PurchaseDate.Value / 30  .. " Days"
	else
		script.Parent.Text = "0 Days"
	end
end)
1 Like

I think you need to learn os.time()
I’m not sure, is it in a localscript? I’m sure they are only serversided scripts.

developer.roblox.com/en-us/api-reference/lua-docs/os

You’ll need to use os.time() on the server to log when the player has joined, I suggest adding a NumberValue in the Player instance which updates occasionally using the subtracted time from the original purchase date which can then be accessed and displayed on a gui or printed in the local F9 console.

Your right probably. I didn’t recall os.time() used in clients.

If the script is done in a localscript then add some remote event then fire it within the client then It’s done I think

Client:



wait(1)
if Player.Data.PurchaseDate.Value == 0 then
	script.Parent.Text = "0 Days"
else
	local subtracted = 30 - Player.Data.PurchaseDate.Value
	print(os.date("*t", subtracted).day)
	
end
Player.Data.PurchaseDate.Changed:Connect(function()
	if Player.Data.PurchaseDate.Value ~= 0 then
		game.ReplicatedStorage:WaitForChild("Event"):FireServer(Player, Player.Data.PurchaseDate.Value)
	else
		script.Parent.Text = "0 Days"
	end
end)

Server:

game.ReplicatedStorage.Event.OnServerEvent:Connect(function(Player, value)
	Player.PlayerGui.Gui.TextLabel.Text = tick() - value
	end)

You could just format the amount of seconds as needed.

Whenever a player purchases a membership, determine if its new or extending an existing one. If it’s new, get the current time from os.time and add how many days the membership is for converted to seconds. If it’s extending, do the same but on the existing time.

Once the player joins, pull the time out of the DataStore to get the future time in seconds as of when the player’s membership should expire and set that as a value that the client can access. This is is where the server stops doing anything; it should not actively update a timer, use client-side prediction and have it count the timer down for the sake of display.

Now that the client has when the membership should expire, it can create a timer and start counting it down. How you get that loop going is up to you but the general idea is that the client will be frequently checking the current time (os.time) and subtracting it from that future seconds value, then formatting it into a usable date format.

Now as to how to format it, we’re going to convert the number of seconds into days. For the sake of UX convenience I’ll also be adding hours but you can remove that yourself is you don’t think you want it. It will have zero padding so that numbers below 10 have a 0 in front to avoid any weird looking formatting.

Here’s an example of time formatting:

-- Seconds in an hour * hours -> 26
local seconds = 3600*26
-- Time format (0d 00h)
local timeFormat = "%dd %.2dh"

-- 60s/m -> 60m/h -> 24h/d
local days = math.floor(seconds/60/60/24)
-- Cap hours via modulus to hours per day
local hours = math.floor((seconds/60/60)%24)

-- Change our formats with string patterns (%d & %.2d)
local timeLeft = timeFormat:format(days, hours)
-- Should be "1d 02h" (or otherwise 26 hours)
print(timeLeft)