I am trying to write some code in Lua. the code is supposed to do this thing: analyze .log file that contains a lot of lines, each line has 3 columns: the first column is time-string format 00:00:00, the second one is [id] and the third is an action- string like log-in, log-out and so on. what I need to do is to print for each worker(id) the average hours per day according to his log-ins and log-outs actions. here is my solution:
function averageHoursPerWorker()
fh,err = io.open("log2.log")
if err ~= nil then
print (err)
return
end
numOfDaysPerWorkerArray = {}
amountOfHoursPerWorkerArray = {}
logInsPerWorker = {}
logOutsPerWorker = {}
hour = ''
worker = ''
action = ''
while true do
stuff = fh.read(fh)
if stuff == nil then break end
lynetab = {}
for i in string.gmatch(stuff,"(%S+)") do
lynetab[#lynetab+1] = i
-- print (i)
end
--here, lynatab contains one line. this is the logic
hour = lynetab[1]
action = lynetab[3]
worker = lynetab[2]
if action == 'log-in' then --save the certain worker log-in hour
logInsPerWorker[worker] = hour
end
if action == 'log-out' then
logOutsPerWorker[worker] = hour --save the certain worker log-out hour
if not (logInsPerWorker[worker] == 0) then --this worker already logged in
if amountOfHoursPerWorkerArray[worker] == nil then --initialize worker's hours%days counter
amountOfHoursPerWorkerArray[worker] = 0
numOfDaysPerWorkerArray[worker] = 0
end
-- print(math.floor(os.difftime(makeTimeStamp(logOutsPerWorker[worker]),makeTimeStamp(logInsPerWorker[worker]))))
--add this hours to worker's hours counter and add one day to days counter of this worker
--i know that the results are wrong- this is because the - operator did not do his job...
--i had no more time to figure it out but i do believe it's something pretty simple to solve.
-- print(GetTimeDifference(logOutsPerWorker[worker],logInsPerWorker[worker]))
amountOfHoursPerWorkerArray[worker] = amountOfHoursPerWorkerArray[worker] + makeTimeStamp(logOutsPerWorker[worker])-makeTimeStamp(logInsPerWorker[worker])
numOfDaysPerWorkerArray[worker] = numOfDaysPerWorkerArray[worker] + 1
logInsPerWorker[worker] = 0
end
end
end
--print the average hours for day per worker
for k,v in pairs(amountOfHoursPerWorkerArray) do
print(k,tonumber(os.date('%H',v))/numOfDaysPerWorkerArray[k])
end
end
I think the problem is with the minus operation on time so I have these function:
function makeTimeStamp(dateString)
local pattern = "(%d+):(%d+):(%d+)"
local xhour, xminute,
xseconds = dateString:match(pattern)
local convertedTimestamp = os.time{ year=0,month=0,day=0,
hour = xhour, minute = xminute, second = xseconds}
return convertedTimestamp
end
and becouse this is not working for me too- I have also this function which doing the difference:
function GetTimeDifference(intialTime,finalTime)
initialHour=tonumber(string.sub(intialTime,1,2)) *3600
initialMinute=tonumber(string.sub(intialTime,4,5))*60
initialSecond=tonumber(string.sub(intialTime,7,8))
finalHour=tonumber(string.sub(finalTime,1,2))*3600
finalMinute=tonumber(string.sub(finalTime,4,5))*60
finalSecond=tonumber(string.sub(finalTime,7,8))
totalInitialTime=initialHour+initialMinute+initialSecond
totalFinalTime=finalHour+finalMinute+finalSecond
local duration=totalFinalTime-totalInitialTime
formatedDuration="00:00:00"
if(duration<10) then
formatedDuration="00:00:0"..duration
elseif(duration>9 and duration<60) then
formatedDuration="00:00:"..duration
elseif(duration>59 and duration<=3600 ) then
--minutes handler
intermediateCalc=(duration/60)
i,j=string.find(tostring(intermediateCalc),".")
if(i==nil and j==nil) then
formatedDuration="00:0"..intermediateCalc
else
min=string.sub(tostring(intermediateCalc),i,j)
if(tonumber(min)<10) then
formatedDuration="00:0"..min
else
formatedDuration="00:"..min
end
end
newSeconds=duration%60
if(newSeconds<10) then
formatedDuration=formatedDuration..":0"
..newSeconds
else
formatedDuration=formatedDuration..":"
..newSeconds
end
else
--hour handler
newMinutes=(finalMinute-initialMinute)/60
if(newMinutes<0) then
newMinutes=newMinutes*-1
end
if(newMinutes<10) then
newMinutes="0"..newMinutes
end
newSeconds=(finalSecond-initialSecond)
if(newSeconds<0) then
newSeconds=newSeconds*-1
end
if(newSeconds<10) then
newSeconds="0"..newSeconds
end
formatedDuration=(finalHour-initialHour)/3600
..":"..newMinutes..":"..newSeconds
end
return formatedDuration
end
still not working... please help!
I'm assuming you are going for a 24h based clock value and that people check out the same day since you didn't specify anything about days being in the data. Assuming this, I'd use a string match pattern, which then modifies the values to a number to work with. Using string.format to generate the same structure for the ouput could something like this:
function calculateWorktime(time_login, time_logout)
login = {time_login:match("(%d+):(%d+):(%d+)")}
logout = {time_logout:match("(%d+):(%d+):(%d+)")}
in_h, out_h = tonumber(login[1]), tonumber(logout[1])
in_m, out_m = tonumber(login[2]), tonumber(logout[2])
in_s, out_s = tonumber(login[3]), tonumber(logout[3])
if out_s < in_s then
out_s = out_s + 60
out_m = out_m - 1
end
if out_m < in_m then
out_m = out_m + 60
out_h = out_h - 1
end
worked_h = out_h - in_h
worked_m = out_m - in_m
worked_s = out_s - in_s
worked_time = ("%02d:%02d:%02d"):format(worked_h, worked_m, worked_s)
return worked_time
end
This generates "14:25:40" with login "08:10:32" and logout "22:36:12"
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.