Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia convert seconds to integer from Dates package: no method matching Int64(::Second)

Tags:

datetime

julia

I'm using the Dates module and I'm trying to convert a Seconds object to an integer.

When I try the following, I get an error:

x = Second(5)
Int(x)
# ERROR: MethodError: no method matching Int64(::Second)

Why doesn't this work? How do I just extract this as a integer value?

My question also applies to converting minutes to integer, days to integer, months to integer, etc.

like image 648
J. Blauvelt Avatar asked Dec 22 '22 23:12

J. Blauvelt


2 Answers

Instead of using an Int constructor, access the .value property of the Second object:

x = Second(5)
x.value # 5

This works for the other objects from the Dates module such as Minute, Day, Month, etc.

Check out @tholy's answer too for a great explanation of why it's structured like this.

As a side note, dump() is a helpful function in situations like this - when you're working with an unfamiliar object and you want to understand how to access its attributes and so forth:

dump(x)
# Output:
# Second
#  value: Int64 5
like image 51
J. Blauvelt Avatar answered May 27 '23 21:05

J. Blauvelt


To expand on the answer from J. Blauvelt, the omission of convert(Int, d) is deliberate. The reason is that convert often implies equivalence, and is used automatically when adding elements to containers:

julia> c = [1,2]
2-element Array{Int64,1}:
 1
 2

julia> push!(c, Second(5))
ERROR: MethodError: Cannot `convert` an object of type Second to an object of type Int64
Closest candidates are:
  convert(::Type{T<:Number}, ::T<:Number) where T<:Number at number.jl:6
  convert(::Type{T<:Number}, ::Number) where T<:Number at number.jl:7
  convert(::Type{T<:Integer}, ::Ptr) where T<:Integer at pointer.jl:23
  ...
Stacktrace:
 [1] push!(::Array{Int64,1}, ::Second) at ./array.jl:853
 [2] top-level scope at none:0

If you allowed this kind of automatic conversion, you could get quite confused: for example, push!(c, Day(5)) would also put 5 into c, and suddenly you're in a situation where you've implied that Day(5) == Second(5).

Now, constructor syntax Int(t) is not the same as convert(Int, t). So in principle, perhaps this could be allowed. But historically the two were intertwined, and there may be a fair amount of code that doesn't distinguish the two.

Consequently, when you're asking for something related to the internal representation, for now it seems better to require the user to exploit that representation directly (e.g., t = Second(5); t.value). Or, write your code in a way that allows you to keep these values along with their units.

like image 45
tholy Avatar answered May 27 '23 23:05

tholy