Julia: InexactError when dividing or multiplying Dates.Millisecond

Created on 2 Mar 2016  路  8Comments  路  Source: JuliaLang/julia

Normal behaviour with second precision:

x_min = DateTime("2016-02-22T16:14:39")
x_max = DateTime("2016-02-22T20:23:51")
x_span = x_max-x_min
println(x_span)
y = x_span/20.0
println(y)

14952000 milliseconds
747600 milliseconds

Behaviour if date times have sub-second precision:

x_min = DateTime("2016-02-22T15:38:45.234")
x_max = DateTime("2016-02-22T19:27:35.363")
x_span = x_max-x_min
println(x_span)
y = x_span/20.0
println(y)

13730129 milliseconds
LoadError: InexactError()
while loading In[51], in expression starting on line 7

in / at dates/periods.jl:49

dates doc

Most helpful comment

I just ran into this problem myself when trying to rescale an interval of time by a Float64 (e.g. then = now(); sleep(0.1); (now() - then)/0.1). As has been said in this thread, there's no automatic rounding in Julia, but with ordinary numbers there is automatic promotion, which sets up an expectation for this sort of operation to work. There may be compelling reasons to have Millisecond be integer-based but this doesn't seem like an operation that should result in an error.

All 8 comments

If you look here https://github.com/JuliaLang/julia/blob/master/base/dates/types.jl#L15-L20
You will see that hours, minutes, seconds, and milliseconds are Int64s

julia> x_min = DateTime("2016-02-22T15:38:45.230")
2016-02-22T15:38:45.23

julia> x_max = DateTime("2016-02-22T19:27:35.360")
2016-02-22T19:27:35.36

julia> x_max-x_min
13730130 milliseconds

julia> (x_max-x_min)/15
915342 milliseconds

julia> (x_max-x_min)/16
ERROR: InexactError()
 in /(::Base.Dates.Millisecond, ::Int64) at ./dates/periods.jl:57
 in eval(::Module, ::Any) at ./boot.jl:267

So if (x_max-x_min)/y) _also_ is to be a Millisecond type, then it will have to return something that can be represented by an Int64, but then you have to use div

div((x_max-x_min),16)
858133 milliseconds

or (if you really want the decimal number)

(x_max-x_min).value/16
858133.125

Indeed, your first example only works because the division of 14952000 by 20 is exact, so the floating point result is converted without loss to an integer.

Note that instead of div, you can use the corresponding operator (\div + [tab]).

I understand this can be annoying, especially for newcomers, but Julia usually doesn't do automatic rounding. @quinnj?

I see! Thanks for clarifying.
I did expect rounding in these functions. I'll keep an eye out in the future if non-rounding is the norm for Julia.

That said, it doesn't make much sense to allow using / given that it will fail most of the time. If we don't want to round automatically, we should at least raise an error and tell the user to use . That would avoid this surprising behavior where it works for some values and not for others.

The same problem happens with non-integer multiplication. In that case, we don't have an equivalent of div, so one needs to use round.

This is the reason why I often have to convert DateTimes to unixtime before plotting with a package like Gadfly, since things like boxplots or density plots require / to behave nicely. I'm not sure what a better solution looks like, but DateTimes are fairly painful to work with at the moment.

Boxplots need to compute the mean so I understand why they fail currently, but why would a density plot fail without /?

I just ran into this problem myself when trying to rescale an interval of time by a Float64 (e.g. then = now(); sleep(0.1); (now() - then)/0.1). As has been said in this thread, there's no automatic rounding in Julia, but with ordinary numbers there is automatic promotion, which sets up an expectation for this sort of operation to work. There may be compelling reasons to have Millisecond be integer-based but this doesn't seem like an operation that should result in an error.

This is unexpected - I expected finding the mean between two dates as (b-a)/2 ... and that actually works almost always, until one day ...

The following code

for i in range(1,length=10)
  println((DateTime(2000,2,1) - DateTime(2000,1,1)) / i)
end

fails at i==7! ... who'd have guessed that (and would have tested for it?)??

Was this page helpful?
0 / 5 - 0 ratings

Related issues

yurivish picture yurivish  路  3Comments

helgee picture helgee  路  3Comments

iamed2 picture iamed2  路  3Comments

StefanKarpinski picture StefanKarpinski  路  3Comments

dpsanders picture dpsanders  路  3Comments