Hello Developers,
I’m currently working on a time manipulation module. This module will provide you with a few basic functions that you can use to handle time in-game and in real life. I’m just wondering that is there is anything I can do to improve this module, what should I add to the module to make it more useful, and what is a good name for this module. I know that the module is bad for some of you so that is why I’m posting this topic to get more ideas so that I can improve the module so that it can be more useful for developers when scripting anything that is related to in-game and real-life time.
Small API:
(Generated by ChatGPT, because I’m too lazy to write all of it)
- GetDateUnit
- Parameters: GetType (string)
- Parameter Type: GetType must be a string.
- Functionality: Retrieves specific date components based on the value of GetType. It returns the day of the week, month, day of the month, year, or a combination of all date components.
- FormatSecondToTime
- Parameters: Seconds (number)
- Parameter Type: Seconds must be a number.
- Functionality: Formats the given number of seconds into a human-readable format, representing the duration in terms of years, months, weeks, days, hours, minutes, and seconds.
- ConvertTimeUnitToSecond
- Parameters: Time (number), UnitName (string)
- Parameter Type: Time must be a number, UnitName must be a string.
- Functionality: Converts the given time value from the specified unit (UnitName) to seconds. Supported units include seconds, minutes, hours, days, weeks, months, years, decades, centuries, and millennia.
- MarkTimestamp
- Parameters: TimeMarkName (string)
- Parameter Type: TimeMarkName must be a string.
- Functionality: Marks the current timestamp with the specified name (TimeMarkName) for future reference.
- GetMarkedTimestamp
- Parameters: TimeMarkName (string)
- Parameter Type: TimeMarkName must be a string.
- Functionality: Retrieves the timestamp marked with the specified name (TimeMarkName).
- UpdateMarkedTimestamp
- Parameters: TimeMarkName (string)
- Parameter Type: TimeMarkName must be a string.
- Functionality: Updates the timestamp marked with the specified name (TimeMarkName) to the current time.
- ViewMarkedTimestamps
- Parameters: None
- Parameter Type: N/A
- Functionality: Prints out all marked timestamps along with their corresponding names.
- GetElapsedSecondSinceTimestamp
- Parameters: TimeMarkName (string)
- Parameter Type: TimeMarkName must be a string.
- Functionality: Calculates the number of seconds elapsed since the timestamp marked with the specified name (TimeMarkName).
- UnmarkTimestamp
- Parameters: TimeMarkName (string)
- Parameter Type: TimeMarkName must be a string.
- Functionality: Removes the timestamp marked with the specified name (TimeMarkName) from the list of marked timestamps.
Module Source:
local TimeModule = {}
local MarkedTimestampNames = {}
local MarkedTimestamps = {}
local MarkTimestampDebounces = {}
local GetTimestampDebounces = {}
local SecondUnit = 1
local MinuteUnit = SecondUnit * 60
local HourUnit = MinuteUnit * 60
local DayUnit = HourUnit * 24
local WeekUnit = DayUnit * 7
local MonthUnit = DayUnit * 30
local YearUnit = DayUnit * 365
local DecadeUnit = YearUnit * 10
local CenturyUnit = DecadeUnit * 10
local MillenniumUnit = CenturyUnit * 10
local OutputMark = '[TimeUtilityModule]: '
local function CheckForYearAndMonthUnitUpdate()
local Month = os.date('%B')
local Year = os.date('%Y')
local function isLeapYear()
return Year % 4 == 0 and (Year % 100 ~= 0 or Year % 400 == 0)
end
local DaysInMonth = {
['January'] = 31,
['February'] = isLeapYear() and 29 or 28,
['March'] = 31,
['April'] = 30,
['May'] = 31,
['June'] = 30,
['July'] = 31,
['August'] = 31,
['September'] = 30,
['October'] = 31,
['November'] = 30,
['December'] = 31,
}
local TotalDaysInYear = 0
for month, days in pairs(DaysInMonth) do
if month == Month then
break
end
TotalDaysInYear = TotalDaysInYear + days
end
local DaysInMonthResult = DaysInMonth[Month]
local DaysInYearResult = TotalDaysInYear
if DaysInMonthResult and DaysInYearResult then
YearUnit = DaysInYearResult
MonthUnit = DaysInMonthResult
else
warn(OutputMark..'Failed to update YearUnit and MonthUnit -> DaysInMonthResult: '..tostring(DaysInMonthResult)..', DaysInYearResult: '..tostring(DaysInYearResult))
end
print(OutputMark..'Finished checking for YearUnit and MonthUnit update!!')
end
CheckForYearAndMonthUnitUpdate()
function TimeModule:GetDateUnit(GetType)
GetType = string.lower(GetType)
local DayOfWeek = os.date('%A')
local Month = os.date('%B')
local DayOfMonth = os.date('%d')
local Year = os.date('%Y')
if GetType == 'dayofweek' then
return DayOfWeek
elseif GetType == 'month' then
return Month
elseif GetType == 'dayofmonth' then
return DayOfMonth
elseif GetType == 'year' then
return Year
elseif GetType == 'all' then
return DayOfWeek..' '..Month..' '..DayOfMonth..' '..Year
else
error(OutputMark..'Invalid GetType. Please try again!!')
end
end
function TimeModule:FormatSecondToTime(Seconds)
Seconds = tonumber(Seconds)
if Seconds < 0 then
error(OutputMark..'Cannot format number less than 0!!')
return
elseif Seconds == math.huge then
error(OutputMark..'Cannot format math.huge to time!!')
return
elseif Seconds == nil then
error(OutputMark..'Argument #1 is not a number!')
return
end
local time_units = {
{MillenniumUnit, "millennium", "millennia"},
{CenturyUnit, "century", "centuries"},
{DecadeUnit, "decade", "decades"},
{YearUnit, "year", "years"},
{MonthUnit, "month", "months"},
{WeekUnit, "week", "weeks"},
{DayUnit, "day", "days"},
{HourUnit, "hour", "hours"},
{MinuteUnit, "minute", "minutes"},
{SecondUnit, "second", "seconds"}
}
local result = {}
for _, unit in ipairs(time_units) do
local value = math.floor(Seconds / unit[1])
Seconds = Seconds % unit[1]
if value ~= 0 then
table.insert(result, string.format("%d %s%s", value, unit[2], value == 1 and "" or "s"))
end
end
if #result ~= 0 then
return table.concat(result, " ")
else
return '0 seconds'
end
end
function TimeModule:ConvertTimeUnitToSecond(Time, UnitName)
UnitName = string.lower(UnitName)
local seconds = 0
if UnitName == 'second' or UnitName == 'seconds' then
seconds = Time
elseif UnitName == 'minute' or UnitName == 'minutes' then
seconds = Time * MinuteUnit
elseif UnitName == 'hour' or UnitName == 'hours' then
seconds = Time * HourUnit
elseif UnitName == 'day' or UnitName == 'days' then
seconds = Time * DayUnit
elseif UnitName == 'week' or UnitName == 'weeks' then
seconds = Time * WeekUnit
elseif UnitName == 'month' or UnitName == 'months' then
seconds = Time * MonthUnit
elseif UnitName == 'year' or UnitName == 'years' then
seconds = Time * YearUnit
elseif UnitName == 'decade' or UnitName == 'decades' then
seconds = Time * DecadeUnit
elseif UnitName == 'century' or UnitName == 'centuries' then
seconds = Time * CenturyUnit
elseif UnitName == 'millennium' or UnitName == 'millennia' then
seconds = Time * MillenniumUnit
else
warn(OutputMark.."Invalid time unit name!!")
end
return seconds
end
function TimeModule:MarkTimestamp(TimeMarkName)
if type(TimeMarkName) ~= 'string' then
error(OutputMark..'Argument #1 expect to be a string not anything else!!')
return
end
if not MarkTimestampDebounces[TimeMarkName] then
MarkedTimestamps[TimeMarkName] = os.time()
table.insert(MarkedTimestampNames, TimeMarkName)
MarkTimestampDebounces[TimeMarkName] = true
end
end
function TimeModule:GetMarkedTimestamp(TimeMarkName)
if type(TimeMarkName) ~= 'string' then
error(OutputMark..'Argument #1 expect to be a string not anything else!!')
return
end
return MarkedTimestamps[TimeMarkName]
end
function TimeModule:UpdateMarkedTimestamp(TimeMarkName)
MarkedTimestamps[TimeMarkName] = os.time()
end
function TimeModule:ViewMarkedTimestamps()
coroutine.wrap(function()
for _, name in ipairs(MarkedTimestampNames) do
print(name .. ': ' .. (MarkedTimestamps[name] or 'No timestamp found in list!!'))
end
end)()
end
function TimeModule:GetElapsedSecondSinceTimestamp(TimeMarkName)
local CurrentTimestamp = os.time()
local MarkedTimestamp = MarkedTimestamps[TimeMarkName]
if MarkedTimestamp then
return CurrentTimestamp - MarkedTimestamp
else
print(OutputMark..'Timestamp can not be found when calculating elapsed seconds!')
return nil
end
end
function TimeModule:UnmarkTimestamp(TimeMarkName)
local Timestamp = MarkedTimestamps[TimeMarkName]
local TimestampName = MarkedTimestampNames[TimeMarkName]
local MarkTimestampDebounce = MarkTimestampDebounces[TimeMarkName]
local GetTimestampDebounce = MarkTimestampDebounces[TimeMarkName]
if Timestamp then
Timestamp = nil
TimestampName = nil
MarkTimestampDebounce = nil
GetTimestampDebounce = nil
print(OutputMark..'Successfully un-marked time stamp!!')
else
print(OutputMark..'Cannot find time stamp in the list to remove!!')
end
end
return TimeModule