# \`range\` of \`DateTime\`s

**URL:** <https://discourse.julialang.org/t/range-of-datetime-s/29060>\
**Category:** New to Julia\
**Tags:** dates\
**Created:** [September 23, 2019, 7:15am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060 "2019-09-23T07:15:26Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 23, 2019, 7:15am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/1 "2019-09-23T07:15:26Z")

</div>

I want to create a uniformly-spaced range of `DateTime` values with e.g. 100 points between two given values. `range` function doesn’t work for me: `range(DateTime(2000, 1, 1, 0, 0), DateTime(2000, 1, 2, 0, 0), length=100)` gives `MethodError: no method matching *(::Float64, ::DateTime)`, and I cannot find an easy way to do this. Note that `range` with `step` instead of `length` does work, e.g.: `range(DateTime(2000, 1, 1, 0, 0), DateTime(2000, 1, 2, 0, 0), step=Minute(1))`.  
Am I missing some obvious solution here?

There was a similar question two years ago here - [Linspace with DateTime](https://discourse.julialang.org/t/linspace-with-datetime/7565) - but there is no answer, and lots of stuff have changed in Julia since then.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 23, 2019, 7:24am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/2 "2019-09-23T07:24:11Z")

</div>

The solution is in that same post:

```julia
function mylinspace(d1::DateTime, d2::DateTime, n::Int)
    Δ = d2 - d1
    T = typeof(Δ)
    δ = T(round(Int, Dates.value(Δ)/(n - 1)))
    d2 = d1 + δ*(n - 1)
    return d1:δ:d2
end

```

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [September 23, 2019, 7:38am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/3 "2019-09-23T07:38:06Z")

</div>

I found this one, because I love comprehensions:

```julia
[DateTime(Dates.UTInstant{Millisecond}(Millisecond(Int64(floor(x))))) for x in range(Dates.value(d1),Dates.value(d2),length=100)]

```

But its not a range, just an array.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 23, 2019, 7:40am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/4 "2019-09-23T07:40:23Z")

</div>

A major difference between this implementation and builtin `range(a, b, length)` (e.g. for numbers) is that the last element of `mylinspace` isn’t equal to `d2` argument. Even more, the last element can be larger that `d2`! And these are just the obvious things I noticed.

Anyway, it’s strange that `range` is not supported for `DateTimes`. This cannot be intentional, right?

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 23, 2019, 7:59am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/5 "2019-09-23T07:59:10Z")

</div>

Yea, I know. You are right that the last element can be larger, that’s a problem. But as to it being equal to `d2` `range` doesn’t do that either:

```julia
julia> range(0, 1, step = 0.11)[end]
0.99

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 23, 2019, 8:06am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/6 "2019-09-23T08:06:00Z")

</div>

`range` with `step` doesn’t, but that’s fine - it’s impossible if `b-a` is not divisible by `step`. But `range` with `length` does have the property that `range(a, b, length)[end] == b` as far as I can see.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [September 23, 2019, 8:07am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/7 "2019-09-23T08:07:33Z")

</div>

Just because the calculated step can be a Float. So range is exact only in the limits of Floats.

---

<div class="post-metadata">

**Author:** ![yakir12](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yakir12/32/297_2.png) [@yakir12](https://discourse.julialang.org/u/yakir12)\
**Post date:** [September 23, 2019, 8:08am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/8 "2019-09-23T08:08:15Z")

</div>

DateTime has a similar limitation in the sense that Nanosecond is the smallset step it can encode.

---

<div class="post-metadata">

**Author:** ![visr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/visr/32/17204_2.png) [@visr](https://discourse.julialang.org/u/visr)\
**Post date:** [September 23, 2019, 11:47am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/9 "2019-09-23T11:47:51Z")

</div>

Perhaps it would be good to create an issue for this?

You can use `range` to create a `LinRange{DateTime}`, though it fails on `show`, or `getindex`. Only `first` seems to work, here on julia 1.3 rc2:

```julia
using Dates
starttime = DateTime(2000, 1, 1, 0, 0)
endtime = DateTime(2000, 1, 2, 0, 0)
r = range(starttime, endtime, length=5); # no error as long as you suppress show with a ;
typeof(r) # -> LinRange{DateTime}
first(r) # -> 2000-01-01T00:00:00
r[1]

```

```nohighlight
ERROR: MethodError: no method matching *(::Float64, ::DateTime)
Closest candidates are:
  *(::Any, ::Any, ::Any, ::Any...) at operators.jl:529
  *(::Float64, ::Float64) at float.jl:405
  *(::AbstractFloat, ::Bool) at bool.jl:112
  ...
Stacktrace:
 [1] unsafe_getindex(::LinRange{DateTime}, ::Int64) at .\range.jl:663
 [2] getindex(::LinRange{DateTime}, ::Int64) at .\range.jl:642

```

---

<div class="post-metadata">

**Author:** ![laborg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laborg/32/5474_2.png) [@laborg](https://discourse.julialang.org/u/laborg)\
**Post date:** [April 12, 2020, 4:40pm UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/10 "2020-04-12T16:40:07Z")

</div>

I filed the issue: [https://github.com/JuliaLang/julia/issues/35446](https://github.com/JuliaLang/julia/issues/35446)

---

<div class="post-metadata">

**Author:** ![Rik](https://avatars.discourse-cdn.com/v4/letter/r/90db22/32.png) [@Rik](https://discourse.julialang.org/u/Rik)\
**Post date:** [March 16, 2023, 2:20pm UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/11 "2023-03-16T14:20:25Z")

</div>

If you are fine with a uniformly-spaced (as good as possible) vector of DateTime values you can compute the range in unix and convert back to DateTime objects. For example:

> function GetTimestampRange(firstTimestamp, lastTimestamp, length)  
> firstTimestampAsUnix = datetime2unix(firstTimestamp)  
> lastTimestampAsUnix = datetime2unix(lastTimestamp)  
> vecOfUnixTimestamps = [range(firstTimestampAsUnix, lastTimestampAsUnix, length = length)…]  
> return unix2datetime.(vecOfUnixTimestamps)  
> end

---

<div class="post-metadata">

**Author:** ![g-gundam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g-gundam/32/47593_2.png) [@g-gundam](https://discourse.julialang.org/u/g-gundam)\
**Post date:** [September 30, 2023, 2:16am UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/12 "2023-09-30T02:16:00Z")

</div>

> [@aplavin](#):
>
> ```julia
> range(DateTime(2000, 1, 1, 0, 0), DateTime(2000, 1, 2, 0, 0), length=100)
> 
> ```

If you’re willing to try **[NanoDates.jl](https://github.com/JuliaTime/NanoDates.jl)**, you can get a range similar to what you wanted originally. However, instead of giving range an integer length, you have to give it a Period.

```julia
using Dates, NanoDates

nd1 = NanoDate(2000, 1, 1, 0, 0)
nd2 = NanoDate(2000, 1, 2, 0, 0)
step = Nanosecond((nd2 - nd1).value ÷ 100) # The division must return an integer.
r100 = nd1:step:nd2
r15m = nd1:Minute(15):nd2
r4h = nd1:Hour(4):nd2

```

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [September 30, 2023, 12:37pm UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/13 "2023-09-30T12:37:04Z")

</div>

What’s the benefit here compared to Dates? They also allow ranges with manually specified steps, as I understand.

---

<div class="post-metadata">

**Author:** ![g-gundam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/g-gundam/32/47593_2.png) [@g-gundam](https://discourse.julialang.org/u/g-gundam)\
**Post date:** [September 30, 2023, 6:05pm UTC](https://discourse.julialang.org/t/range-of-datetime-s/29060/14 "2023-09-30T18:05:25Z")

</div>

I should have experimented a little bit more before posting. My newness to Julia is showing, and I didn’t realize DateTime could do nearly the same thing in this case.
