简体   繁体   中英

How to do difference between 2 times objects in lua?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM