Reputation: 21
I am currently working on a plugin for grandMA2 lighting control using Lua. I need the current time. The only way to get the current time is the following function:
gma.show.getvar('TIME')
which always returns the current system time, which I then store in a variable. An example return value is "12h54m47.517s"
.
How can I separate the hours, minutes and seconds into 3 variables?
Upvotes: 2
Views: 1055
Reputation: 2813
Lets do it with string method gsub()
local ts = gma.show.getvar('TIME')
local hours = ts:gsub('h.*', '')
local mins = ts:gsub('.*%f[^h]', ''):gsub('%f[m].*', '')
local secs = ts:gsub('.*%f[^m]', ''):gsub('%f[s].*', '')
To make a Timestring i suggest string method format()
-- secs as float
timestring = ('[%s:%s:%.3f]'):format(hours, mins, secs)
-- secs not as float
timestring = ('[%s:%s:%.f]'):format(hours, mins, secs)
Upvotes: 1
Reputation: 11191
If os.date
is available (and matches gma.show.getvar('TIME')
), this is trivial:
If format starts with '!', then the date is formatted in Coordinated Universal Time. After this optional character, if format is the string "*t", then date returns a table with the following fields: year, month (1–12), day (1–31), hour (0–23), min (0–59), sec (0–61, due to leap seconds), wday (weekday, 1–7, Sunday is 1), yday (day of the year, 1–366), and isdst (daylight saving flag, a boolean). This last field may be absent if the information is not available.
local time = os.date('*t')
local hour, min, sec = time.hour, time.min, time.sec
This does not provide you with a sub-second precision though.
Otherwise, parsing the time string is a typical task for tostring
and string.match
:
local hour, min, sec = gma.show.getvar('TIME'):match('^(%d+)h(%d+)m(%d*%.?%d*)s$')
-- This is usually not needed as Lua will just coerce strings to numbers
-- as soon as you start doing arithmetic on them;
-- it still is good practice to convert the variables to the proper type though
-- (and starts being relevant when you compare them, use them as table keys or call strict functions that check their argument types on them)
hour, min, sec = tonumber(hour), tonumber(min), tonumber(sec)
Pattern explanation:
^
and $
pattern anchors: Match the full string (and not just part of it), making the match fail if the string does not have the right format.(%d)+h
: Capture hours: One or more digits followed by a literal h
(%d)+m
: Capture minutes: One or more digits followed by a literal m
(%d*%.?%d*)s
: Capture seconds: Zero or more digits followed by an optional dot followed by again zero or more digits, finally ending with a literal s
. I do not know the specifics of the format and whether something like .1s
, 1.s
or 1s
is occasionally emitted, but Lua's tonumber supports all of these so there should be no issue. Note that this is slightly overly permissive: It will also match .
(just a dot) and an s
without any leading digits. You might want (%d+%.?%d+)s
instead to force digits appearing before & after the dot.Upvotes: 3