# DateTime: Time division

**URL:** <https://discourse.julialang.org/t/datetime-time-division/95285>\
**Category:** General Usage\
**Tags:** dates, algebra\
**Created:** [February 27, 2023, 7:40pm UTC](https://discourse.julialang.org/t/datetime-time-division/95285 "2023-02-27T19:40:48Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [February 27, 2023, 7:40pm UTC](https://discourse.julialang.org/t/datetime-time-division/95285/1 "2023-02-27T19:40:48Z")

</div>

I was wondering how division works on time intervals.

My naïve thought doesn’t work

```julia
using Dates
hr = Dates.Hour(1)
t1 = DateTime(2023, 1, 3)
r = 7.4
t2 = t1 + hr/r # ->InexactError: Int64(0.13513513513513511)

```

The following works only for some values of `r`:

```julia
tdummy = t1 + hr
t2 = t1 + (tdummy - t1).value / r # -> works only for some values of r

```

`tdummy - t1` is of type `Millisecond` and if the division results in an integer, the above code works.

The following works in general:

```julia
tdummy = t1 + hr
t2 = t1 + Dates.Millisecond(round((tdummy - t1).value/r))

```

But, is this really what’s intended? I thought there should be a more elegant solution.

What is the standard way to express “t1 + onehour/r” for a general real number `r` ? It seems to me that we need a proper “time interval type” which works seamlessly with `DateTime`.

---

<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:** [February 27, 2023, 8:05pm UTC](https://discourse.julialang.org/t/datetime-time-division/95285/2 "2023-02-27T20:05:18Z")

</div>

Yeah, float-based time intervals are often more convenient than integers. Julia doesn’t have them in stdlib, unfortunately.  
See _(my)_ [`DateFormats.jl`](https://gitlab.com/aplavin/DateFormats.jl) package that helps dealing with different date/time formats, including decimal periods:

```julia
julia> using Dates, DateFormats

julia> DateTime(2023, 1, 3) + 1/7.4 *ₜ Hour
2023-01-03T00:08:06.486

```

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [February 27, 2023, 8:45pm UTC](https://discourse.julialang.org/t/datetime-time-division/95285/3 "2023-02-27T20:45:19Z")

</div>

Note that you can convert from lower to higher precision time periods where the answer is always the same (so you can do `Millisecond(Hour(1))` but not `Day(Month(1))`). This just skips the need for your dummy variable:

```julia
using Dates
hr = Dates.Hour(1)
t1 = DateTime(2023, 1, 3)
r = 7.4
t1 + Millisecond(round(Millisecond(hr).value/r))

```

This does seem annoying. But the reason all sorts of fractional arithmetic doesn’t just work is because

> Period types represent discrete, human representations of time.

as opposed to physical durations of time. The [`lubridate` cheatsheet](https://evoldyn.gitlab.io/evomics-2018/ref-sheets/R_lubridate.pdf) for `R` is good for seeing how complex things need to be to support date arithmetic fully.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [February 27, 2023, 8:50pm UTC](https://discourse.julialang.org/t/datetime-time-division/95285/4 "2023-02-27T20:50:11Z")

</div>

Check also this [related thread](https://discourse.julialang.org/t/operations-with-time-duration/64983).

From which your example could be written, with the help of `CompoundPeriods`, as:

```julia
using Dates, CompoundPeriods
import Base: / , *
/(t::Dates.CompoundPeriod, x::Real) = canonicalize(Dates.CompoundPeriod(Millisecond(round(Int64,Dates.toms(t)/x))))
*(t::Dates.CompoundPeriod, x::Real) = canonicalize(Dates.CompoundPeriod(Millisecond(round(Int64,Dates.toms(t)*x))))

hr = Hour(1) |> CompoundPeriod
t1 = DateTime(2023, 1, 3)
r = 7.4
t2 = t1 + hr/r # 2023-01-03T00:08:06.486

```

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [February 28, 2023, 6:46am UTC](https://discourse.julialang.org/t/datetime-time-division/95285/5 "2023-02-28T06:46:35Z")

</div>

Thanks!

Your code is corrupted on my screen (webbrowser) but I get what it is:

```julia
DateTime(2023, 1, 3) + period_decimal(Hour, 1/7.4)

```

from the automatic email message sent me by [discoursemail.com](http://discoursemail.com) .

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [February 28, 2023, 6:54am UTC](https://discourse.julialang.org/t/datetime-time-division/95285/6 "2023-02-28T06:54:26Z")

</div>

> [@Jollywatt](#):
>
> > Period types represent discrete, human representations of time.
> 
> as opposed to physical durations of time.

Thanks. I understand that. I understand that the `Dates` package isn’t designed with this usage in mind.

The original motivation of my post is to ask whether there is already a standard method to handle physical duration of time.

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [February 28, 2023, 7:19am UTC](https://discourse.julialang.org/t/datetime-time-division/95285/7 "2023-02-28T07:19:07Z")

</div>

In the future, it would be nice if “we” have

```julia
using FloatingDates
del = Hour(1.25) # a CompoundPeriod
t1 = DateTime(2023, 1, 3) # a floating-point version
r = 7.4
t2 = t1 + del/r

```

to use `CompoundPeriod` implicitly.

I keep needing DateTime arithmetics in such a construct as

```julia
t1 = DateTime( . . . )
t2 = DateTime( . . . )
del = Hour(1) + Minute(30)
time_axis = (t1 + del/2):del:(t2 - del/2)
@assert length(time_axis) == length(somedata)
plot(time_axis, somedata)

```

because I sometimes have to deal with datasets without a proper time axis.

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [February 28, 2023, 9:06am UTC](https://discourse.julialang.org/t/datetime-time-division/95285/8 "2023-02-28T09:06:30Z")

</div>

> [@ryofurue](#):
>
> The original motivation of my post is to ask whether there is already a standard method to handle physical duration of time.

In that case, do consider `Unitful.jl`:

> [@Operations with time duration](https://discourse.julialang.org/t/operations-with-time-duration/64983/10):
>
> ```julia
> julia> using Unitful
> 
> julia> t = 1u"hr" + 5u"minute" + 2u"s"
> 3902 s
> 
> julia> t/5
> 780.4 s
> 
> ```

Incidentally, your desired code does work if you change the compound period `del = Hour(1) + Minute(30)` to a simple period `del = Minute(90)`.

```julia
t1 = DateTime("2023-01-01")
t2 = DateTime("2023-01-02")
del = Minute(90)
time_axis = (t1 + del/2):del:(t2 - del/2)

```

I wonder why using a compound period as a range step isn’t implemented? Perhaps we can get it added!

---

<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:** [February 28, 2023, 10:21am UTC](https://discourse.julialang.org/t/datetime-time-division/95285/9 "2023-02-28T10:21:38Z")

</div>

> [@ryofurue](#):
>
> Thanks!
> 
> Your code is corrupted on my screen (webbrowser) but I get what it is:
> 
> ```julia
> DateTime(2023, 1, 3) + period_decimal(Hour, 1/7.4)
> 
> ```
> 
> from the automatic email message sent me by [discoursemail.com](http://discoursemail.com) .

That also works, and was indeed my message before I edited it. I recently noticed that multiplication/division is more natural for this operation than the `period_decimal` function, and made a new `DateFormats` version with `*ₜ` and `/ₜ` operators. This message prompted me to actually release the new version, so I updated the message on discourse.  
Meaning of `1/7.4 *ₜ Hour` is more obvious than `period_decimal(Hour, 1/7.4)`, so I suggest using this operator.

---

<div class="post-metadata">

**Author:** ![ryofurue](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ryofurue/32/24531_2.png) [@ryofurue](https://discourse.julialang.org/u/ryofurue)\
**Post date:** [February 28, 2023, 11:36am UTC](https://discourse.julialang.org/t/datetime-time-division/95285/10 "2023-02-28T11:36:03Z")

</div>

> [@Jollywatt](#):
>
> > [@ryofurue](#):
> >
> > The original motivation of my post is to ask whether there is already a standard method to handle physical duration of time.
> 
> In that case, do consider `Unitful.jl`:

You seem to ignore the context of this discussion: It seems to me that you lift my words out of the context and propose a solution that doesn’t work in the present context. The following code doesn’t work:

```julia
using Dates
using Unitful
del = 1u"hr" + 5u"minute" + 2u"s"
t1 = DateTime(2023, 1, 29)
t2 = t1 + del/5 # MethodError: no method matching +(::DateTime, . . .

```

From the context of this discussion, it’s clear that I’m wanting a method to handle physical duration of time **together with `DateTime`.** (But, it would be nice if `Dates` worked with the time in the `Unitful` package.)

> [@Jollywatt](#):
>
> Incidentally, your desired code does work if you change the compound period del = Hour(1) + Minute(30) to a simple period del = Minute(90).

I know that! Yours isn’t my “desired code”. Again you lift my example out of the context. The code you wrote stops working once we introduce division:

```julia
t1 = DateTime(2023, 1, 29)
t2 = DateTime(2023, 5, 29)
del = Minute(90) / 3.14
time_axis = (t1 + del/2):del:(t2 - del/2)

```

**Wanting a time interval type that allows for usual arithmetics as if it were a floating-point number together with DateTime, is the starting point of this discussion!**
