Skip to content

Latest commit

 

History

History
146 lines (133 loc) · 6.15 KB

Time [DEPRECATED].md

File metadata and controls

146 lines (133 loc) · 6.15 KB

Deprecated Date function

-- Extends the os table to include the full os.date functionality included in vanilla Lua
-- @readme https://github.com/RoStrap/Time/blob/master/README.md
-- @author Validark

-- Necessary data tables
local Suffixes = {"st", "nd", "rd"}
local DayNames = {[0] = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
local MonthNames = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
local MonthLengths = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

local function IsLeapYear(Year)
	return Year % 4 == 0 and (Year % 25 ~= 0 or Year % 16 == 0)
end

local function GetMonthLength(Month, Year)
	return Month == 2 and IsLeapYear(Year) and 29 or MonthLengths[Month]
end

-- Localize functions
local function Date(StringToFormat, UnixSeconds)
	--- Allows you to use os.date in RobloxLua!
	--		date ([format [, time]])
	-- This doesn't include the explanations for the math. If you want to see how the numbers work, see the following:
	-- http://howardhinnant.github.io/date_algorithms.html#civil_from_days
	--
	-- @param string StringToFormat
	--		If present, function date returns a string formatted by the tags in StringToFormat.
	--		If StringToFormat starts with "!", date is formatted in UTC.
	--		If StringToFormat is "*t", date returns a table
	--		Placing "_" in the middle of a tag (e.g. "%_d" "%_I") removes padding
	--		String Reference: https://github.com/Narrev/NevermoreEngine/blob/patch-5/Modules/Utility/readme.md
	--		@default "%c"
	--
	-- @param number UnixSeconds
	--		If present, UnixSeconds is the time to be formatted. Otherwise, date formats the current time.
	--		The amount of Seconds since 1970 (negative numbers are occasionally supported)
	--		@default tick()

	-- @returns a string or a table containing date and time, formatted according to the given string format. If called without arguments, returns the equivalent of date("%c").

	-- Find whether StringToFormat was used
	if StringToFormat then
		if type(StringToFormat) == "number" then -- If they didn't pass a StringToFormat, and only passed UnixSeconds through
			if type(UnixSeconds) == "string" then error("Invalid parameters passed to os.date. Your parameters might be in the wrong order") end
			UnixSeconds, StringToFormat = StringToFormat, "%c"
		elseif type(StringToFormat) == "string" then
			if not StringToFormat:find("*t") and not StringToFormat:find("%%[_cxXTrRaAbBdHIjMmpsSuwyY]") then
				warn("[os.date] \"" .. StringToFormat .. "\" has nothing to format")
			end
			local UTC
			StringToFormat, UTC = StringToFormat:gsub("^!", "") -- If StringToFormat begins in '!', use os.time()
			-- if UTC == 1 and UnixSeconds then warn("Cannot determine time to format for os.date: Use either an \"!\" at the beginning of the string OR pass a time parameter") end
			UnixSeconds = UnixSeconds or UTC == 1 and os.time()
		end
	else -- If they did not pass a formatting string
		StringToFormat = "%c"
	end

	-- Set UnixSeconds
	UnixSeconds = tonumber(UnixSeconds) or tick()

	-- Get Hours, Minutes, and Seconds
	local Hours = math.floor(UnixSeconds / 3600 % 24)
	local Minutes = math.floor(UnixSeconds / 60 % 60)
	local Seconds = math.floor(UnixSeconds % 60)

	-- Get Days, Month and Year
	local Days = math.floor(UnixSeconds / 86400) + 719468
	local WeekDay = (Days + 3) % 7 -- Day of week with Sunday @0 [0, 6]
	local Year = math.floor((Days >= 0 and Days or Days - 146096) / 146097) -- 400 Year bracket
	Days = (Days - Year * 146097) -- Days into 400 Year bracket [0, 146096]
	local Years = math.floor((Days - math.floor(Days / 1460) + math.floor(Days / 36524) - math.floor(Days / 146096)) / 365)	-- Years into 400 Year bracket[0, 399]
	Days = Days - (365 * Years + math.floor(Years / 4) - math.floor(Years / 100)) -- Days into Year with March 1st @0 [0, 365]
	local Month = math.floor((5 * Days + 2) / 153) -- Month with March @0 [0, 11]
	local YearDay = Days
	Days = Days - math.floor((153 * Month + 2) / 5) + 1 -- Days into Month [1, 31]
	if (Month < 10) then
		YearDay = YearDay + 31 + (IsLeapYear(Year) and 28 or 29)
	else
		YearDay = YearDay - 273 - 32
	end
	Month = Month + (Month < 10 and 3 or -9) -- Actual Month [1, 12]
	Year = Years + Year*400 + (Month < 3 and 1 or 0) -- Actual Year

	-- table.foreach(Time.Date("*t", 34*86400 + os.time() - 7*3600), print)
	-- TODO: Fix yearday

	if StringToFormat == "*t" then -- Return a table if "*t" was used
		return {year = Year, month = Month, day = Days, yday = YearDay, wday = WeekDay, hour = Hours, min = Minutes, sec = Seconds}
	end

	-- Return formatted string
	return (
		StringToFormat
			:gsub("%%c",  "%%x %%X")
			:gsub("%%_c", "%%_x %%_X")
			:gsub("%%x",  "%%m/%%d/%%y")
			:gsub("%%_x", "%%_m/%%_d/%%y")
			:gsub("%%X",  "%%H:%%M:%%S")
			:gsub("%%_X", "%%_H:%%M:%%S")
			:gsub("%%T",  "%%I:%%M %%p")
			:gsub("%%_T", "%%_I:%%M %%p")
			:gsub("%%r",  "%%I:%%M:%%S %%p")
			:gsub("%%_r", "%%_I:%%M:%%S %%p")
			:gsub("%%R",  "%%H:%%M")
			:gsub("%%_R", "%%_H:%%M")
			:gsub("%%a", DayNames[WeekDay]:sub(1, 3))
			:gsub("%%A", DayNames[WeekDay])
			:gsub("%%b", MonthNames[Month]:sub(1, 3))
			:gsub("%%B", MonthNames[Month])
			:gsub("%%d", ("%02d"):format(Days))
			:gsub("%%_d", Days)
			:gsub("%%H", ("%02d"):format(Hours))
			:gsub("%%_H", Hours)
			:gsub("%%I", ("%02d"):format(Hours > 12 and Hours - 12 or Hours == 0 and 12 or Hours))
			:gsub("%%_I", Hours > 12 and Hours - 12 or Hours == 0 and 12 or Hours)
			:gsub("%%j", ("%02d"):format(YearDay))
			:gsub("%%_j", YearDay)
			:gsub("%%M", ("%02d"):format(Minutes))
			:gsub("%%_M", Minutes)
			:gsub("%%m", ("%02d"):format(Month))
			:gsub("%%_m", Month)
			:gsub("%%n", "\n")
			:gsub("%%p", Hours >= 12 and "pm" or "am")
			:gsub("%%_p", Hours >= 12 and "PM" or "AM")
			:gsub("%%s", (Days < 21 and Days > 3 or Days > 23 and Days < 31) and "th" or Suffixes[Days % 10])
			:gsub("%%S", ("%02d"):format(Seconds))
			:gsub("%%_S", Seconds)
			:gsub("%%t", "\t")
			:gsub("%%u", WeekDay == 0 and 7 or WeekDay)
			:gsub("%%w", WeekDay)
			:gsub("%%Y", Year)
			:gsub("%%y", ("%02d"):format(Year % 100))
			:gsub("%%_y", Year % 100)
			:gsub("%%%%", "%%")
	)
end

return {
	Date = Date;
	IsLeapYear = IsLeapYear;
	GetMonthLength = GetMonthLength;
}