Creating a Calendar System

I have glanced through devlogs trying to figure out how to make a calendar system, but it doesn’t quite work for me. What I want to do is create a calendar to view the date. Meaning I need the day to line up with the day of the week, and I would also need it to be TextButtons. The only way I thought would be to make a calendar script with a start time of the date using os, but that didn’t seem practical. Is there a better way to go about this? Also, there are challenges like leap year.

You can actually identify when leap years occur!

Every 4 years, a leap year happens.
Every 100 years, it doesn’t happen, unless that year is divisible by 400.


I cannot code it right now, but you can try to make a system for it

  1. Try to see if it’s a leap year
  2. See if it can be divisible by 100 and 400

Ok, my biggest issue was setting up the numbers to go down the colums of the week days

have you tried the date library?

https://www.lua.org/pil/22.1.html

also what is oc?

Leap year shouldn’t be a problem because Roblox got the % symbol

local CurrentYear = tonumber(os.date("%Y"))

if CurrentYear % 4 == 0 then
    print(CurrentYear.. " is a valid leap year")
end

Now as for checking how many months a day has, setting up a simple module script should help

local months = {
	["MonthName"] = 30 
}

Repeat it 12 times with the right amount of days and you should be good.

As for other stuff (such as dates and weeks), you should look into the link HellaHarrdd provided

1 Like

I meant os, but I didn’t know this existed, thank you. Only one issue does this work with different time zones?

os.date("%c",os.time()) will get you the date and time like so: Tue Mar 5 01:10:35 2024

Ok, I understand that, and I used a module script and created this, but there are errors where when I go back and forth the buttons don’t load, can anyone help me out?

-- CalendarModule

local module = {}

local pageNum = 0
local pageCap = 2
local monthsDistance = nil

local Months = {"January", "Febuary", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
local daysOfTheWeek = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}

local function calDaysOfYear(currentYear)
	if currentYear % 4 == 0 then
		local amountOfDays = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
		return amountOfDays
	else
		local amountOfDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
		return amountOfDays
	end	
end

local function calculateDay(numberDay, dayOfWeek, spots: Folder)
	local week = math.floor(numberDay/7)
	local calc1 = 0
	calc1 = 7 * week
	local key = "Spot"
	local btn
	
	if dayOfWeek == "Sunday" then
		calc1 += 1
		btn = spots:FindFirstChild(key..calc1)
	elseif dayOfWeek == "Monday" then
		calc1 += 2
		btn = spots:FindFirstChild(key..calc1)
	elseif dayOfWeek == "Tuesday" then
		calc1 += 3
		btn = spots:FindFirstChild(key..calc1)
	elseif dayOfWeek == "Wednesday" then
		calc1 += 4
		btn = spots:FindFirstChild(key..calc1)
	elseif dayOfWeek == "Thursday" then
		calc1 += 5
		btn = spots:FindFirstChild(key..calc1)
	elseif dayOfWeek == "Friday" then
		calc1 += 6
		btn = spots:FindFirstChild(key..calc1)
	elseif dayOfWeek == "Saturday" then
		calc1 += 7
		btn = spots:FindFirstChild(key..calc1)
	end
	
	print(calc1, dayOfWeek)
	
	return btn
end

local function doAllCalc(daysOfTheMonths, monthNum, NumDay, dayOfTheWeek, NumberSpots)
	local lastDayOfLastMonth
	local beginDay
	
	local amountOfMonthDays = daysOfTheMonths[monthNum]
	local ForwardInt = amountOfMonthDays - NumDay
	local backwardInt = (amountOfMonthDays - 1) - ForwardInt

	local week = math.floor(NumDay/7)

	local actualBtn = calculateDay(NumDay, dayOfTheWeek, NumberSpots)
	actualBtn.Visible = true
	actualBtn.Text = NumDay
	local numBtn = string.split(actualBtn.Name, "t")[2]

	for i = 1, ForwardInt do
		local btnHere = NumberSpots:FindFirstChild("Spot"..i+numBtn)
		btnHere.Visible = true
		btnHere.Text = NumDay + i

		if i == ForwardInt then
			local numInstance = string.split(btnHere.Name, "t")[2]
			local num2 = numInstance%7
			lastDayOfLastMonth = daysOfTheWeek[num2 + 1]
		end
	end

	for i = 1, backwardInt do
		local btnHere = NumberSpots:FindFirstChild("Spot"..numBtn-i)
		btnHere.Visible = true
		btnHere.Text = NumDay - i
		
		if i == backwardInt then
			local numInstance = string.split(btnHere.Name, "t")[2]
			local num2 = numInstance%7
			beginDay = daysOfTheWeek[num2 - 1]
		end
	end
	
	return lastDayOfLastMonth, beginDay
end

local function calcButtonsFunctions(daysOfTheMonths, monthNum, NumDay, dayOfTheWeek, NumberSpots)
	print(dayOfTheWeek)
	
	for _, btn: TextButton in ipairs(NumberSpots:GetChildren()) do
		btn.Visible = false
	end
	
	local beginDay
	local lastDayOfLastMonth
	
	repeat wait(0.1)
		for _, buton: TextButton in ipairs(NumberSpots:GetChildren()) do
			if buton.Text == "1" then
				local splitName = string.split(buton.Name, "t")[2]
				local num2 = splitName%7
				beginDay = daysOfTheWeek[num2]
			end
		end
	until beginDay ~= nil
		
	local amountOfMonthDays = daysOfTheMonths[monthNum]
	local ForwardInt = amountOfMonthDays - NumDay

	local week = math.floor(NumDay/7)

	local actualBtn = calculateDay(NumDay, dayOfTheWeek, NumberSpots)
	actualBtn.Visible = true
	actualBtn.Text = NumDay
	local numBtn = string.split(actualBtn.Name, "t")[2]
	

	for i = 1, ForwardInt do
		local btnHere = NumberSpots:FindFirstChild("Spot"..i+numBtn)
		btnHere.Visible = true
		btnHere.Text = NumDay + i

		if i == ForwardInt then
			local numInstance = string.split(btnHere.Name, "t")[2]
			local num2 = numInstance%7
			lastDayOfLastMonth = daysOfTheWeek[num2 + 1]
		end
	end
	
	return lastDayOfLastMonth, beginDay
end

function module.createCalendar(calendarFrame, forwardBtn: TextButton, backBtn: TextButton, NumberSpots: Folder)
	local currentMonth = os.date("%B")
	local month = os.date("%m")
	local monthNum = tonumber(month)
	local currentYear = os.date("%Y")
	local dayOfTheWeek = os.date("%A")
	local day = os.date("%d")
	local NumDay = tonumber(day)
	
	monthsDistance = monthNum
	
	local monthLabel = calendarFrame.monthLabel
	
	local lastDayOfLastMonth
	
	monthLabel.Text = currentMonth..", "..currentYear
	
	local daysOfTheMonths = calDaysOfYear(currentYear)
	
	local lastDay, beginDay = doAllCalc(daysOfTheMonths, monthNum, NumDay, dayOfTheWeek, NumberSpots)
	
	forwardBtn.MouseButton1Click:Connect(function()
		pageNum += 1
		backBtn.Visible = true
		if pageNum >= pageCap then
			forwardBtn.Visible = false
		end
		
		monthsDistance += 1
		monthLabel.Text = Months[monthsDistance]..", "..currentYear
		
		lastDay, beginDay = calcButtonsFunctions(daysOfTheMonths, monthsDistance, 1, lastDay, NumberSpots)
	end)
	
	backBtn.MouseButton1Click:Connect(function()
		pageNum -= 1
		forwardBtn.Visible = true
		if pageNum <= 0 then
			backBtn.Visible = false
		end
		
		monthsDistance -= 1
		monthLabel.Text = Months[monthsDistance]..", "..currentYear
		
		lastDay, beginDay = calcButtonsFunctions(daysOfTheMonths, monthsDistance, 1, beginDay, NumberSpots)
	end)
end

return module

Video of issues:
YouTube Video

In the video you notice that the textboxes slowly get off kilter, and I don’t know how to fix it, so if someone could pelase help me that would be awesome!