# Data frame sum of a Time column

Simple (I hope): how to sum the Time column (d) of 15:52:31 + 15:52:31 + 15:52:31 giving 47:34:33

Your current type is `Time`, which is a time in a day. You canβt add two times in a day together.

What you want is a `Period`

``````julia> t1 = Dates.CompoundPeriod(Hour(15), Minute(52), Second(31));

julia> t2 = Dates.CompoundPeriod(Hour(2), Minute(25), Second(10));

julia> t1 + t2
17 hours, 77 minutes, 41 seconds
``````
1 Like

NB: the sum should be `47:37:33`

Also, the addition of CompoundPeriods does not seem sufficient:

``````t1 = Dates.CompoundPeriod(Hour(15), Minute(52), Second(31))
t1 + t1 + t1
45 hours, 156 minutes, 93 seconds
``````

One attempt here below, based on this Rosetta code:

``````using Dates, DataFrames

function HHMMSS_duration(sec)
t = Int[]
for dm in (60, 60)
sec, m = divrem(sec, dm)
pushfirst!(t, m)
end
pushfirst!(t, sec)
return Dates.CompoundPeriod(Hour(t[1]), Minute(t[2]), Second(t[3]))
end

df = DataFrame(a=1:3, d=Dates.Time.(["15:52:31","15:52:31","15:52:31"], "H:M:S"))

s = cumsum(Dates.value.(df.d))/1e9
df.cumsum = HHMMSS_duration.(s)

julia> df
Row β a      d         cumsum
β Int64  Time      Compoundβ¦
ββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββ
1 β     1  15:52:31  15 hours, 52 minutes, 31 seconds
2 β     2  15:52:31  31 hours, 45 minutes, 2 seconds
3 β     3  15:52:31  47 hours, 37 minutes, 33 seconds
``````

`canonicalize` might help. It does what its name implies or what this example shows:

``````julia> cp = Dates.CompoundPeriod(Hour(2),Minute(100),Second(5))
2 hours, 100 minutes, 5 seconds

julia> canonicalize(cp)
3 hours, 40 minutes, 5 seconds
``````

If we take the OP example, it produces:

``````t1 = Dates.CompoundPeriod(Hour(15), Minute(52), Second(31))
canonicalize(t1 + t1 + t1)

1 day, 23 hours, 37 minutes, 33 seconds
``````

Adding times of the day makes no sense. `(15:00)*3=45:00` assumes that there is something special about midnight, but it just depends on which offset you choose.

Of course it doesnβt, and Peter already mentioned it above: a different type should be used. Meanwhile, if we reinterpret them as durations, how can we proceed?

1 Like

`Time` is essentially nanoseconds so this should work?

``````julia> t1 = Time(15, 52, 31)
julia> t2 = Time(15, 52, 31)
julia> t3 = Time(15, 52, 31)

julia> canonicalize(t1.instant + t2.instant + t3.instant)
1 day, 23 hours, 37 minutes, 33 seconds
``````

Thank you all and so I did two things with the second function feeling rather clumsyβ¦(but Iβm learning stuff). Q. How do you pass a data column name by reference to a function i.e. total_time(accepted.Time).

βTotal a dataframe Time column in Weeks, Days, Hours, Minutes and Secondsβ
function total_time_formal(xxx)
t = Dates.CompoundPeriod(Hour(0), Minute(0), Second(0))
for i in 1:nrow(xxx)
t += Dates.CompoundPeriod(xxx.Time[i])
end
return canonicalize(t)
end

βTotal a dataframe Time column for HH:MM:SS i.e. hundreds of hours:minutes:secondsβ
function total_time()
t1 = t2 = t3 = 0.0 # hours, minutes, seconds
for i in 1:nrow(accepted)
t1 += Dates.hour(accepted.Time[i])
t2 += Dates.minute(accepted.Time[i])
t3 += Dates.second(accepted.Time[i])
end
t2 += modf(t3 / 60)[2] # whole seconds to minutes
t3 = modf(t3 / 60)[1] * 60 # residual seconds
t1 += modf(t2 / 60)[2] # whole minutes to hours
t2 = modf(t2 / 60)[1] * 60 # residual minutes
return t1, t2, t3
end

Another way to convert higher periods (days, weeks) to hours:

``````julia> hourify(t) = begin
tt = canonicalize(t) ;
pushfirst!(tt.periods, sum(Hour.(splice!(tt.periods,1:findlast(in([Hour,Day,Week]), typeof.(tt.periods))))))
end
hourify (generic function with 1 method)

julia> hourify(Second(123121414))
3-element Vector{Period}:
34200 hours
23 minutes
34 seconds
``````

The positive about this method is keeping the calculations hidden at the Dates module. Perhaps the technique willl be of sum use.