# Constructing dates from a vector of numbers?

**URL:** <https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546>\
**Category:** New to Julia\
**Created:** [October 17, 2020, 3:29pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546 "2020-10-17T15:29:27Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 17, 2020, 3:29pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/1 "2020-10-17T15:29:27Z")

</div>

I have a solution of a differential equations problem, with a given time vector, say 50 values in the range [0,10]. I want to use date along the abscissa axis in the plot. So essentially, I want to associate time 0 from the differential equation to, say, October 1, 2020, and so on.

Question: Is there a way to take a vector, say `time = range(0,10,length=50)` and add an initial date so that the result becomes a vector of dates?

Question: Would I have to interpolate the solution of the differential equation at integer times to achieve this?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 17, 2020, 3:54pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/2 "2020-10-17T15:54:13Z")

</div>

> [@BLI](#):
>
> and so on.

Not clear enough, if you have 0 as Oct 1st, what would 0.20408 (second element in your `time` array) be, Oct 2nd? if so, then you only really care how long the `time` vector is:

```julia
julia> time_d = range(Date(2020, 10, 1); step=Day(1), length=length(time))
Date("2020-10-01"):Day(1):Date("2020-11-19")

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 17, 2020, 4:06pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/3 "2020-10-17T16:06:33Z")

</div>

This is not quite what I need. This would be pretending that the time step is 1 day, but it is not. Differential equation solvers typically use variable step length.

Still, your answer helps me if I interpolate the solution once a day.

It is possible that I need to use `DateTime` (??) to handle it properly. And – you have a point: I need to specify which time of day the clock starts.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [October 17, 2020, 4:07pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/4 "2020-10-17T16:07:31Z")

</div>

yes you need DateTime for finer grain

I did fixed step size because your `time` has fixed step.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 17, 2020, 6:45pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/5 "2020-10-17T18:45:32Z")

</div>

Here is approximately what I was looking for:

```julia
function add_float2datetime(x,datetime)
    d = Int(floor(x))
    e = x-d
    h = Int(floor(e*24))
    e = e-h/24
    m = Int(floor(e*24*60))
    e = e-m/24/60
    s = Int(floor(e*24*60*60))
    e = e-s/24/60/60
    ms = Int(floor(e*24*60*60*1e3))
    return datetime+Day(d)+Hour(h)+Minute(m)+Second(s)+Millisecond(ms)
end
#
dt = DateTime(2020,10,1)
x = range(0,10,length=50)
#
add_float2datetime.(x,dt)

```

leading to:

```julia
50-element Array{DateTime,1}:
 2020-10-01T00:00:00
 2020-10-01T04:53:52.653
 2020-10-01T09:47:45.306
 2020-10-01T14:41:37.959
 ⋮
 2020-10-10T09:18:22.04
 2020-10-10T14:12:14.693
 2020-10-10T19:06:07.346
 2020-10-11T00:00:00

```

My function is not elegant… it could have been improved with test on argument types, and generalized in case `x` is something else than day.

Two other improvements…

- I could have skipped the “add to” part, i.e., argument `datetime` if it had been possible to create a `DateTime` type with zero value for month… Maybe there is another way to do that.
- Perhaps this function already exists? My second HP calculator, the HP-29c (produced in 1975; I bought it in 1979 or so), had functions → H.MS and -\>H .

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [October 17, 2020, 8:06pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/6 "2020-10-17T20:06:23Z")

</div>

It can be written shorter in this way

```julia
using Dates
import Dates: DateTime

function Dates.DateTime(x::Float64, origin = DateTime(0))
    time = Millisecond(Int(floor(Millisecond(Day(1)).value * x)))
    return origin + time
end

```

with the result

```julia
julia> dt = DateTime(2020,10,1)
2020-10-01T00:00:00

julia> x = range(0,10,length=50)
0.0:0.20408163265306123:10.0

julia> DateTime.(x, dt)
50-element Array{DateTime,1}:
 2020-10-01T00:00:00
 2020-10-01T04:53:52.653
 2020-10-01T09:47:45.306
 2020-10-01T14:41:37.959

```

On the other hand, you can remove `origin` and convert time periods to time periods and adding origin later

```julia
function timeperiod(x::Float64)
    Millisecond(Int(floor(Millisecond(Day(1)).value * x)))
end

```

and

```julia
julia> timeperiod.(x)
50-element Array{Dates.CompoundPeriod,1}:
 empty period
 17632653 milliseconds
 35265306 milliseconds
 52897959 milliseconds
 70530612 milliseconds
 88163265 milliseconds
 105795918 milliseconds

julia> dt + timeperiod.(x)
50-element Array{DateTime,1}:
 2020-10-01T00:00:00
 2020-10-01T04:53:52.653
 2020-10-01T09:47:45.306
 2020-10-01T14:41:37.959
 2020-10-01T19:35:30.612
 2020-10-02T00:29:23.265
 2020-10-02T05:23:15.918

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 17, 2020, 9:54pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/7 "2020-10-17T21:54:44Z")

</div>

> [@Skoffer](#):
>
> ```julia
> using Dates
> import Dates: DateTime
> 
> function Dates.DateTime(x::Float64, origin = DateTime(0))
> time = Millisecond(Int(floor(Millisecond(Day(1)).value * x)))
> return origin + time
> end
> 
> ```

Very nice!

What is not clear to me…

- do you _add_ a method to function `DateTime` here?
- in other words: does your function definition constitute a modification/new method to the `Dates` package? [Probably not? By adding this function with name `Dates.DateTime`, it is only defined in the current session…??]

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [October 17, 2020, 11:29pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/8 "2020-10-17T23:29:32Z")

</div>

> [@BLI](#):
>
> do you _add_ a method to function `DateTime` here?

Yes. Well, not me, but @Skoffer does that, 😅.

> [@BLI](#):
>
> does your function definition constitute a modification/new method to the `Dates` package?

Yes. All now calls to `Dates.DateTime` can end up ambiguous because of that. This is the reason [Type Piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy) is not encouraged. If he added a new method using a a new type introduced by them, then there would be no risk of some code (loaded before this change and unaware of it) end up calling the new method when it was not wanted.

Addendum: @Skoffer did specifically `import` that function because if you get a function name by means of `using` you cannot add a new method to it, so as a safety net to avoid doing something disastrous without noticing.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [October 18, 2020, 7:53am UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/9 "2020-10-18T07:53:00Z")

</div>

Sorry for this confusion, I should have warn you that this is type piracy and it is not needed at all. You may use any other function name (like `add_datetime`) and it’ll work just fine.

On the other hand, it is not a first time I see request for constructing date time from float value, so I suppose it worth a PR to Dates or at least small separate package.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 18, 2020, 6:54pm UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/10 "2020-10-18T18:54:54Z")

</div>

A design choice of `timeperiod(x;...)` is: should one allow the user to specify (i) the time unit of `x` (Day? Hour? etc.) and the accuracy (millisecond? second? etc.).

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [October 19, 2020, 6:33am UTC](https://discourse.julialang.org/t/constructing-dates-from-a-vector-of-numbers/48546/11 "2020-10-19T06:33:50Z")

</div>

You should do what best suits your needs 🙂  
But the time unit is nice and rather cheap to implement, so why not?

```julia
using Dates

function timeperiod(x::Float64, timeunit=Day(1))
    Millisecond(Int(floor(Millisecond(timeunit).value * x)))
end

```

with an outcome

```julia
julia> origin = DateTime("2020-10-01")
2020-10-01T00:00:00

julia> x = range(0,10,length=50)
0.0:0.20408163265306123:10.0

julia> origin + timeperiod.(x)
50-element Array{DateTime,1}:
 2020-10-01T00:00:00
 2020-10-01T04:53:52.653
 2020-10-01T09:47:45.306
 2020-10-01T14:41:37.959

julia> origin + timeperiod.(x, Hour(1))
50-element Array{DateTime,1}:
 2020-10-01T00:00:00
 2020-10-01T00:12:14.693
 2020-10-01T00:24:29.387
 2020-10-01T00:36:44.081

julia> origin + timeperiod.(x, Day(7))
50-element Array{DateTime,1}:
 2020-10-01T00:00:00
 2020-10-02T10:17:08.571
 2020-10-03T20:34:17.142
 2020-10-05T06:51:25.714

```
