# Converting units of time deltas

**URL:** <https://discourse.julialang.org/t/converting-units-of-time-deltas/63944>\
**Category:** General Usage\
**Tags:** dates\
**Created:** [July 2, 2021, 2:48pm UTC](https://discourse.julialang.org/t/converting-units-of-time-deltas/63944 "2021-07-02T14:48:17Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![evanfields](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/evanfields/32/1744_2.png) [@evanfields](https://discourse.julialang.org/u/evanfields)\
**Post date:** [July 2, 2021, 2:48pm UTC](https://discourse.julialang.org/t/converting-units-of-time-deltas/63944/1 "2021-07-02T14:48:17Z")

</div>

Let’s say I want to get the fractional hours elapsed between two times. I often have code that looks something like

```julia
function hours_elapsed(start, stop)
    millis = (stop - start).value
    return millis / (1000 * 60 * 60)
end

```

This seems nasty for two reasons:

- Trusting `start - stop` to return a `Millisecond` and not some other period type seems dangerous. Maybe `start` and `stop` are some other datetime-like type where subtraction returns a `Second`, not a `Millisecond`.
- The above snippet is quite a mouthful.

What’s the preferred way to convert some elapsed time to a fractional number of time units?

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [July 2, 2021, 3:12pm UTC](https://discourse.julialang.org/t/converting-units-of-time-deltas/63944/2 "2021-07-02T15:12:28Z")

</div>

You can use `Millisecond(stop-start)` to be sure you have milliseconds. But that will fail if the period is not an integer number of milliseconds. Safer would be to use

```julia
function hours_elapsed(start, stop)
    nanos = Nanosecond(stop - start)
    return Dates.value(nanos) * 1e-9 / 3600
end

```

though maybe not optimal for precision? (and no less of a mouthful than your example)

---

<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:** [July 2, 2021, 4:31pm UTC](https://discourse.julialang.org/t/converting-units-of-time-deltas/63944/3 "2021-07-02T16:31:43Z")

</div>

Couldn’t you use the functions: `Dates.datetime2epochms` and `Dates.epochms2datetime` ?

---

<div class="post-metadata">

**Author:** ![George9000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/george9000/32/23619_2.png) [@George9000](https://discourse.julialang.org/u/George9000)\
**Post date:** [July 3, 2021, 3:08am UTC](https://discourse.julialang.org/t/converting-units-of-time-deltas/63944/4 "2021-07-03T03:08:53Z")

</div>

```julia
using Dates
stop = now()
start = now() - Minute(90)
round((stop - start), Minute)/Minute(60)

```

For comparisons,

```julia
round((stop - start), Minute)/Minute(60) < 2*Minute(60).value

```

> <https://github.com/JuliaLang/julia/pull/24182>
>
> Allows (most) subtypes of \`Period\` to be rounded with \`floor\`, \`ceil\`, and \`roun…d\`, also allowing for easy conversion between \`Period\` subtypes where we would otherwise encounter an \`InexactError\`.
> 
> \`\`\`julia
> julia\> x = Dates.Millisecond(29394943)
> 29394943 milliseconds
> 
> julia\> convert(Dates.Hour, x)
> ERROR: InexactError: divexact(Int64, 8.165261944444444)
> Stacktrace:
> \[1\] divexact(::Int64, ::Int64) at ./dates/periods.jl:400
> \[2\] convert(::Type{Base.Dates.Hour}, ::Base.Dates.Millisecond) at ./dates/periods.jl:422
> 
> julia\> round(x, Dates.Hour)
> 8 hours
> \`\`\`
> 
> As with the date rounding functions, this approach also supports rounding to values (e.g., the nearest 15 minutes) as well as types:
> 
> \`\`\`julia
> julia\> x = Dates.Hour(910)
> 910 hours
> 
> julia\> ceil(x, Dates.Hour(12))
> 912 hours
> \`\`\`
> 
> I can see at least two potential concerns being raised about this approach:
> 1. As discussed in https://github.com/JuliaLang/julia/issues/18574, there may be some confusion/contention surrounding the typical rounding signature (\`round(value, precision)\`) and the convert signature (\`convert(type, value)\`).
> 2. ~For certain very large values, the rounding may still result in an \`InexactError\`. This is because all values are converted to \`Nanosecond\` for rounding, so we can't easily accommodate values that exceed \`typemax(Int64)\` nanoseconds (which is a little over 292 years). This could be mitigated by using a lower-precision \`Period\` type when nanosecond precision is not required.~
> 
> \*\*Edit:\*\* Point 2 above has been mitigated via \`promote\`.

---

<div class="post-metadata">

**Author:** ![dehann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dehann/32/2003_2.png) [@dehann](https://discourse.julialang.org/u/dehann)\
**Post date:** [May 12, 2022, 6:22pm UTC](https://discourse.julialang.org/t/converting-units-of-time-deltas/63944/5 "2022-05-12T18:22:40Z")

</div>

Hi,

This is perhaps more a Dates.jl design question, but is there any reason Dates.jl cannot be extended to support fractional hours via e.g. `Hour{Float64}`. Currently,

```julia
julia> Hour{Float64}
ERROR: TypeError: in Type{...} expression, expected UnionAll, got Type{Hour}
Stacktrace:
 [1] top-level scope
   @ REPL[13]:1

```

Just curious how the community feels about something like this?
