I have a DataTable with two columns of time and I want to compute the time duration between these 2 columns. The problem I have is to compute a duration with Nullable type.
julia> a, b
(Nullable{String}("14:00:00"),Nullable{String}("15:15:00"))
julia> b-a
ERROR: MethodError: no method matching -(::String, ::String)
in -(::Nullable{String}, ::Nullable{String}) at /home/fred/.julia/v0.5/NullableArrays/src/operators.jl:132
julia> convert(Dates.Minute,a)
ERROR: MethodError: Cannot `convert` an object of type Nullable{String} to an object of type Base.Dates.Minute
This may have arisen from a call to the constructor Base.Dates.Minute(...),
since type constructors fall back to convert methods.
julia> Dates.DateTime(a,"HH:MM")
ERROR: MethodError: Cannot `convert` an object of type Nullable{String} to an object of type Int64
This may have arisen from a call to the constructor Int64(...),
since type constructors fall back to convert methods.
in DateTime(::Nullable{String}, ::String) at ./dates/types.jl:116
a, b = (Nullable{String}("14:00:00"),Nullable{String}("15:15:00"))
Base.Dates.Time(str::String) = Dates.Time(map(x->parse(Int, x), split(str, ':'))...)
difflift(a, b) = (isnull(a) || isnull(b)) ? Nullable{Dates.Nanosecond}() : Nullable{Dates.Nanosecond}(b - a)
aT, bT = Dates.Time(get(a)), Dates.Time(get(b))
difflift(aT, bT)
The idea here is you’re doing “lifting” on the nullable arguments in case either is actually null. Also, this is currently using 0.6 code where the Dates.Time type has been added. You could also use a DateTime without too much trouble since you’re just looking for the difference.
@quinnj Thank you very much for your answer. I did not imagine it was so complex to compute a time difference
I am currently using Julia 5.0 and I have this result :
julia> aT, bT = DateTime(get(a)), DateTime(get(b))
ERROR: ArgumentError: Delimiter mismatch. Couldn't find first delimiter, "-", in date string
in parse(::String, ::Base.Dates.DateFormat) at ./dates/io.jl:169
in DateTime(::String) at ./dates/io.jl:268
@nalimilan
I tried on julia 0.6 and I still have a problem to convert nanoseconds to minutes for example
julia> Base.Dates.Time(str::String) = Dates.Time(map(x->parse(Int, x), split(str, ':'))...)
julia> a2 = Dates.Time.(a)
Nullable{Base.Dates.Time}(14:00:00)
julia> b2 = Dates.Time.(b)
Nullable{Base.Dates.Time}(15:15:00)
julia> b2 .- a2
Nullable{Base.Dates.Nanosecond}(4500000000000 nanoseconds)
julia> Int(b2 .- a2)
ERROR: MethodError: Cannot `convert` an object of type Nullable{Base.Dates.Nanosecond} to an object of type Int64
This may have arisen from a call to the constructor Int64(...),
since type constructors fall back to convert methods.
Stacktrace:
[1] Int64(::Nullable{Base.Dates.Nanosecond}) at ./sysimg.jl:24
julia> c=b2 .- a2
Nullable{Base.Dates.Nanosecond}(4500000000000 nanoseconds)
julia> c/1e3
ERROR: MethodError: no method matching /(::Nullable{Base.Dates.Nanosecond}, ::Float64)
Closest candidates are:
/(::Float64, ::Float64) at float.jl:377
/(::BigFloat, ::Union{Float16, Float32, Float64}) at mpfr.jl:343
/(::Complex, ::Real) at complex.jl:268
...
with the solution of @cormullion it finaly works better on Julia 0.5 because all operations on times are possible
Everything which works in Julia 0.5 also works on 0.6. The question is, do you want to extract the value from the Nullable wrapper immediately (which implies that no null values are possible): then use get first. OTOH, if you need to support missing values, then keep the Nullable, but then you need to use .(, .-, etc. for all operations.
Thank you very much @nalimilan ! I understand better the role of the get function.
Since, to my knowledge, this useful function does not appear in the DataTables documentation, a short explanation how to extract the value from the Nullable wrapper would be very useful in the section “The Nullable Type”.
julia> c = b2 .- a2
Nullable{Base.Dates.Nanosecond}(4500000000000 nanoseconds)
julia> d = get(c)
4500000000000 nanoseconds
julia> Int(d)
4500000000000
julia> Int(d)/1e9
4500.0
Yeah, that section of the DataTables manual could be improved. It should also point to the relevant section of the Julia manual. Would you make a pull request to change this?
@nalimilan I tried to make a pull request (for the first time ) and I did not succeed. I did not find the “documentation” section of DataTables.jl on GitHub.
Do I have to fork the whole JuliaData/DataTables.jl directory to make a pull request ? Then on the “Compare changes” I don’t know what to choose. Sorry for asking those questions, but it is unclear of that works