Ilya Kharmatsky - 2014-01-15

I workaround the lack of implementation of the:

  • os.time - return result in seconds
  • os.time - parse date table argument if provided
  • os.date - format according to the strftime patterns
  • os.date - format the date table if argument is 't' or '!t'

by providing the own implementation of the functionality described above.

I used the utility class from Apache Tomcat project to be able to parse the strftime formatting options. Read the limitation of the Apache Strftime class.

I plan to translate the same business logic into the pure Java implementation later. You can run this script from LuaJ environment (tested with 2.0.3 version).

Here is the patch:

~~~~~~~~~~~~~
:::lua
local calendar_class = luajava.bindClass("java.util.Calendar")
local tz_class = luajava.bindClass("java.util.TimeZone")
local java_system = luajava.bindClass("java.lang.System")

os.time = function (t)
if not t then
return java_system:currentTimeMillis() / 1000
end

assert(type(t) == 'table', 'Unsupported type of argument of os.time method')
local calendar = calendar_class:getInstance()
for k,v in pairs(t) do
    if     k == 'hour'  then calendar:set(11, v) -- Calendar.HOUR_OF_DAY value
    elseif k == 'min'   then calendar:set(12, v) -- Calendar.MINUTE value
    elseif k == 'wday'  then calendar:set(7, v)  -- Calendar.DAY_OF_WEEK
    elseif k == 'year'  then calendar:set(1, v)  -- Calendar.YEAR
    elseif k == 'yday'  then calendar:set(6, v)  -- Calendar.DAY_OF_YEAR
    elseif k == 'month' then calendar:set(2, v-1)-- Calendar.MONTH (java starts with 0)
    elseif k == 'sec'   then calendar:set(13, v) -- Calendar.SECOND
    elseif k == 'day'   then calendar:set(5, v)  -- Calendar.DAY
    end
end
return calendar:getTime():getTime() / 1000

end

os.date=function(f,t)
if not t then
t = os.time()
end

assert(type(f)=='string' and type(t)=='number', 'Unsupported types for os.date method')
local date = luajava.newInstance("java.util.Date", t * 1000)

if f == '*t' or f == '!*t' then
    local res = {}
    local tz = (f == '*t') and tz_class:getDefault() 
                    or tz_class:getTimeZone('UTC') 
    local calendar = (f == '*t') and calendar_class:getInstance() 
                    or calendar_class:getInstance(tz)

    calendar:setTime(date)
    res.hour  = calendar:get(11) -- Calendar.HOUR_OF_DAY value
    res.min   = calendar:get(12) -- Calendar.MINUTE
    res.wday  = calendar:get(7)  -- Calendar.DAY_OF_WEEK
    res.year  = calendar:get(1)  -- Calendar.YEAR
    res.yday  = calendar:get(6)  -- Calendar.DAY_OF_YEAR
    res.month = calendar:get(2) + 1 -- Calendar.MONTH note, that Java Calendar starts with 0
    res.sec   = calendar:get(13) -- Calendar.SECOND
    res.day   = calendar:get(5)  -- Calendar.DAY_OF_MONTH
    res.isdst = tz:inDaylightTime(date)
    return res
end

local strftime_java = luajava.newInstance("org.apache.catalina.util.Strftime", f)

return strftime_java:format(date)

end

~~~~~~