learnin'
One the tracks on Exercism I found interesting is Lua. Lua and Tcl are kind of in the same arena: small languages often embedded in other applications.
Lua is far smaller than Tcl, with less builtin functionality, but it’s still quite capable (and extremely fast).
Lua OO is kind of tricky to wrap your head around. You’re either going to pick a closure-based approach (where the constructor function will return a table containing function elements and access the data from the constructor function’s scope), or you’re going to pick a metatable-based approach (which more closely resembles “traditional” OO class/instance style).
Since metatables are a new concept to a lot of Lua students, I wrote an article about it. Unfortunately, it’s kind of hidden on the Exercism website, so I’ll reproduce it here.
2026-03-01
Regarding the utility of the os.date formatting string and the ! prefix.
The problem is that the ! converts the time value from local time to UTC time.
There’s no way to use os.time to interpret the table it’s given as already being in UTC: I’m in the Eastern TZ
> t = {['year']=2014, ['month']=11, ['day']=1, ['hour']=20, ['min']=0, ['sec']=0}
> epoch = os.time(t)
> epoch
1414886400
> os.date('%c', epoch)
Sat Nov 1 20:00:00 2014
> os.date('!%c', epoch)
Sun Nov 2 00:00:00 2014
The hour=20 is treated as the local time.
I can’t tell Lua that I wish the input time table to be 8pm in UTC.
Consider GNU date command: you get a different time value when you tell it the input time is in UTC
$ date -d '2014-11-01 20:00:00' '+%s'
1414886400
$ date -d '2014-11-01 20:00:00' --utc '+%s'
1414872000
IMO, if you’re parsing a datetime string, manipulating it, and then formatting it back into a string, ! is not helpful.
These tests are only passing because %x only considers the date part
(the canonical data expects the full datetime).
I’m working on the swift-scheduling exercise in moonscript and I’m considering adding the date rock to the test-runner. With this luarock:
date = require 'date'
-- to find a date object's epoch time in seconds is a bit clunky:
-- subtract the epoch date from the dateObj and get the seconds from the delta.
function totime(dateObj)
return (dateObj - date.epoch()):spanseconds()
end
utc = date('2014-11-01 20:00:00')
print(totime(utc)) -- 1414872000.0 -- same as GNU date with --utc flag
edt = date('2014-11-01 20:00:00 EDT')
print(totime(edt)) -- 1414886400.0
Now we can see that we need a UTC time value to get the date in UTC:
-- UTC timestamp with a local format string is _wrong_
print(os.date('%F %T', totime(utc))) -- 2014-11-01 16:00:00
-- UTC timestamp with a UTC format string is _right_
print(os.date('!%F %T', totime(utc))) -- 2014-11-01 20:00:00
-- local timestamp with a local format string is _right_
print(s.date('%F %T', totime(edt))) -- 2014-11-01 20:00:00
-- local timestamp with a UTC format string is _wrong_
print(s.date('!%F %T', totime(edt))) -- 2014-11-02 00:00:00
…
My rant gets somewhat blunted when I actually read the canonical-data and see
“Most test programs currently check only the date and ignore the time.”,
Sigh.