# How can I convert a CompoundPeriod type object to Period type in Julia?

**URL:** https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930
**Category:** General Usage
**Tags:** dates, convert
**Created:** [May 11, 2021, 5:24am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930 "2021-05-11T05:24:08Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![shubh\_b](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shubh_b/32/20697_2.png) [@shubh\_b](https://discourse.julialang.org/u/shubh_b)
#### Post date: [May 11, 2021, 5:24am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/1 "2021-05-11T05:24:08Z")

</div>

Using `Dates` module in Julia I am able to transform a `Period` type object (`Hour`, `Minute`, `Second`, `Day` etc.) to another `Period` type as below:

```julia
using Dates

julia> convert(Day, Hour(96))
4 days

julia> convert(Second, Hour(20))
72000 seconds

```

But if I try to convert any `CompoundPeriod` type object (`Hour(2) + Minute(20)`, `Week(3) + Day(5)` etc.), it throws an error as below:

```julia
julia> convert(Second, Hour(3) + Minute(12))
ERROR: MethodError: Cannot `convert` an object of type Dates.CompoundPeriod to an object of type Second

```

Here, 3 hours + 12 minutes = 11520 seconds  
Is there a Julia function to find the number of seconds (11520 seconds) in this case?  
How can I convert a `CompoundPeriod` type object to `Period` type in Julia?

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [May 11, 2021, 7:58am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/2 "2021-05-11T07:58:10Z")

</div>

I don’t think there is a nice way to do this right now (but it would be good to add it). You can use `Dates.tons` or `Dates.toms` to convert a `CompoundPeriod` to a number in nanoseconds or milliseconds, but it will be a floating-point number, so you might lose some precision. For example, you could do

```julia
julia> c = Hour(3) + Minute(12)
3 hours, 12 minutes

julia> convert(Second, Millisecond(Dates.toms(c)))
11520 seconds

```

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [May 11, 2021, 8:30am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/3 "2021-05-11T08:30:36Z")

</div>

Another way, which does not use floating-point numbers, is the following:

```julia
julia> c = Hour(3) + Minute(12)
3 hours, 12 minutes

julia> sum(Second, c.periods)
11520 seconds

```

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [May 12, 2021, 1:22pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/4 "2021-05-12T13:22:34Z")

</div>

I have made a [PR](https://github.com/JuliaLang/julia/pull/40803) to enable conversion of `CompoundPeriod`s to `Period`s.

---

<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: [May 12, 2021, 2:16pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/5 "2021-05-12T14:16:04Z")

</div>

Don’t know, if this is a good idea. From the docs:

```julia
help?> Dates.CompoundPeriod
  CompoundPeriod

  A CompoundPeriod is useful for expressing time periods that are not a fixed multiple of smaller periods. For
  example, "a year and a day" is not a fixed number of days, but can be expressed using a CompoundPeriod.

```

From this definition it seems clear, why there isn’t such a thing.  
Of course, one can argue, that it should be available and do the conversion for those CompoundPeriods, where it is uniquely possible, like for hours+minutes to seconds.  
Should it raise an error/exception for year+month e.g. into days?

I didn’t look into your PR, so perhaps you have already thought of all this issues.

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [May 12, 2021, 2:24pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/6 "2021-05-12T14:24:07Z")

</div>

The conversion only works for `CompoundPeriods` for which all contained `Period`s can be converted. Otherwise, it throws a `MethodError`.

---

<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: [May 12, 2021, 3:25pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/7 "2021-05-12T15:25:53Z")

</div>

nice

---

<div class="post-metadata">

### Author: ![shubh\_b](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shubh_b/32/20697_2.png) [@shubh\_b](https://discourse.julialang.org/u/shubh_b)
#### Post date: [May 16, 2021, 8:48am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/8 "2021-05-16T08:48:39Z")

</div>

Thank you @sostock . This is the best way so far 🙂

---

<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: [September 28, 2021, 11:54pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/9 "2021-09-28T23:54:14Z")

</div>

Fyi:

```julia
using Dates, CompoundPeriods
t = Hour(3) + Minute(12)
Seconds(t) # 11520 seconds

```

---

<div class="post-metadata">

### Author: ![anon91151494](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@anon91151494](https://discourse.julialang.org/u/anon91151494)
#### Post date: [October 23, 2024, 11:13am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/10 "2024-10-23T11:13:55Z")

</div>

Should this be `Second` not `Seconds`?

---

<div class="post-metadata">

### Author: ![anon91151494](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@anon91151494](https://discourse.julialang.org/u/anon91151494)
#### Post date: [October 23, 2024, 11:19am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/11 "2024-10-23T11:19:51Z")

</div>

> [@shubh\_b](#):
>
> How can I convert a `CompoundPeriod` type object to `Period` type in Julia?

As a more general question, I don’t understand what the intention behind `CompoundPeriod` is.

- Could someone explain how / what it is supposed to be used for?

I understand that a `CompoundPeriod` is a collection of `Periods`, and that it can be constructed from a `Vector{Period}`.

However, what can be done with it after this? There is a `canonicalize` function which converts (assuming I understand correctly) a `CompoundPeriod` into another `CompoundPeriod`. It redistributes the quantities assigned to each `Period` component of a `CompoundPeriod` in the canonical way.

Beyond that - is there anything else you can do with a `CompoundPeriod`?

Sorry I’m somewhat confused because I don’t appear to be able to do any of the following things:

- convert it to a `Period`
- print it (format it as a `String`)
- convert it to a number of `Seconds`, either as an integer or floating point number of “seconds”
- convert it to a `Time` or `TimePeriod` or some other “duration” type

I would have guessed that I should be able to do one or more of the above operations?

---

<div class="post-metadata">

### Author: ![anon91151494](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@anon91151494](https://discourse.julialang.org/u/anon91151494)
#### Post date: [October 23, 2024, 11:56am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/12 "2024-10-23T11:56:45Z")

</div>

I’ve discovered you _can_ convert a `CompoundPeriod` to a `Time` type, if the duration is less than 24 hours.

```julia
Dates.Time(compound_period.periods...)

```

If it exceeds 24 hours, I think you have a problem

---

<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: [October 23, 2024, 12:33pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/13 "2024-10-23T12:33:27Z")

</div>

> [@anon91151494](#):
>
> Should this be `Second` not `Seconds`?

I think we should use CompoundPeriods.jl Seconds():

```julia
using Dates, CompoundPeriods
t = Hour(3) + Minute(12)
Seconds(t) # 11520 seconds
Second(t) # 0 seconds

```

---

<div class="post-metadata">

### Author: ![anon91151494](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@anon91151494](https://discourse.julialang.org/u/anon91151494)
#### Post date: [October 23, 2024, 1:08pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/14 "2024-10-23T13:08:11Z")

</div>

I think I’m getting confused or otherwise doing something incorrectly.

Do you happen to know why this isn’t working?

```julia
julia> using Dates

julia> t=Hour(3)+Second(12)
3 hours, 12 seconds

julia> Dates.CompoundPeriods.Seconds(t)
ERROR: UndefVarError: CompoundPeriods not defined
Stacktrace:
 [1] getproperty(x::Module, f::Symbol)
   @ Base ./Base.jl:31
 [2] top-level scope
   @ REPL[3]:1

```

I also tried

```julia
julia> CompoundPeriods(t)
ERROR: UndefVarError: CompoundPeriods not defined
Stacktrace:
 [1] top-level scope
   @ REPL[4]:1

```

---

<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: [October 23, 2024, 1:16pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/15 "2024-10-23T13:16:15Z")

</div>

You missed loading the package:

```julia
using CompoundPeriods

```

---

<div class="post-metadata">

### Author: ![anon91151494](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@anon91151494](https://discourse.julialang.org/u/anon91151494)
#### Post date: [October 23, 2024, 1:21pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/16 "2024-10-23T13:21:19Z")

</div>

Ok thanks. I’ve realized I am asking the wrong questions - DateTimes in Julia has had me going around in circles for an hour or so

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [October 23, 2024, 2:31pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/17 "2024-10-23T14:31:34Z")

</div>

> [@anon91151494](#):
>
> Do you happen to know why this isn’t working?

The CompoundPeriods.jl package is a third-party package. I would recommend sticking with the Dates standard library for now. (Note that the composite period type is `Dates.CompoundPeriod`, without an `s` at the end.)

Regarding your other questions, it’s been a while since I’ve used the Dates standard library (I use Python at work these days), but I can attempt to answer them.

> [@anon91151494](#):
>
> convert it to a `Period`

I believe that the `Period` and `CompoundPeriod` types should be mostly interchangeable, so you shouldn’t need to do a manual conversion from one to the other.

> [@anon91151494](#):
>
> print it (format it as a `String`)

Not sure if this is what you are looking for:

```julia-repl
julia> cp = Month(1) + Day(1)
1 month, 1 day

julia> string(cp)
"1 month, 1 day"

```

There is the `Dates.format` function for formatting times as strings, but note that it only works for subtypes of `Dates.TimeType` (i.e. `Date`, `Time`, and `DateTime`). Periods, durations, and compound periods are not subtypes of `TimeType`.

> [@anon91151494](#):
>
> convert it to a number of `Seconds`, either as an integer or floating point number of “seconds”

A period or compound period represents a calendar period, which does not have a well-defined duration. So, for instance, `Month(1) + Day(1)` is a compound period that represents “a month and a day”. But the number of seconds in `Month(1) + Day(1)` depends on the month that you are talking about. So, the `second` extractor doesn’t work on a period:

```julia-repl
julia> second(Month(1) + Day(1))
ERROR: MethodError: no method matching second(::Dates.CompoundPeriod)

Closest candidates are:
  second(::DateTime)
   @ Dates C:\Users\U216145\AppData\Local\Programs\Julia-1.9.0\share\julia\stdlib\v1.9\Dates\src\accessors.jl:62
  second(::Time)
   @ Dates C:\Users\U216145\AppData\Local\Programs\Julia-1.9.0\share\julia\stdlib\v1.9\Dates\src\accessors.jl:66

```

> [@anon91151494](#):
>
> convert it to a `Time` or `TimePeriod` or some other “duration” type

Typically what you do with a period is add it to a `TimeType` to get a new `TimeType`, like this:

```julia-repl
julia> t = now()
2024-10-23T09:26:41.859

julia> p = Month(1) + Day(1)
1 month, 1 day

julia> t + p
2024-11-24T09:26:41.859

```

---

<div class="post-metadata">

### Author: ![anon91151494](https://avatars.discourse-cdn.com/v4/letter/a/838e76/32.png) [@anon91151494](https://discourse.julialang.org/u/anon91151494)
#### Post date: [October 23, 2024, 2:58pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/18 "2024-10-23T14:58:33Z")

</div>

> [@CameronBieganek](#):
>
> Not sure if this is what you are looking for:
> 
> ```julia
> julia> cp = Month(1) + Day(1)
> 1 month, 1 day
> 
> julia> string(cp)
> "1 month, 1 day"
> 
> ```

Sorry, to clarify I meant with some customizable format. I was assuming the `format` function call might work with something like a `String` to specify the format. eg `HH:MM:SS`, etc

> [@CameronBieganek](#):
>
> A period or compound period represents a calendar period, which does not have a well-defined duration.

Ah yes, ok then it’s reasonable such a thing is not implemented. I should have realized this.

Let me re-think what I want to ask here.

---

<div class="post-metadata">

### Author: ![hhaensel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hhaensel/32/1207_2.png) [@hhaensel](https://discourse.julialang.org/u/hhaensel)
#### Post date: [November 18, 2024, 11:23am UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/19 "2024-11-18T11:23:08Z")

</div>

Just want to give my 5 cents to this topic, as it came up to me every now and then during work on different projects.  
If the duration does not comprise Month or Year you can always convert back to a period. Just make sure you use the lowest occurring unit.  
Hence,

```julia
convert(Nanosecond, cp)

```

is a safe bet.  
If you are interested in converting to the lowest occurring unit you can define

```julia
function toperiod(cp::Dates.CompoundPeriod)::Period
    p = Dates.periods(ei)
    isempty(p) ? Millisecond(0) : convert(typeof(last(p)), cp)
end

```

Where I deliberately chose to convert zero compund periods to Milliseconds, as that is (currently) the lowest unit of `now()`.

---

<div class="post-metadata">

### Author: ![shubh\_b](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shubh_b/32/20697_2.png) [@shubh\_b](https://discourse.julialang.org/u/shubh_b)
#### Post date: [November 20, 2024, 1:08pm UTC](https://discourse.julialang.org/t/how-can-i-convert-a-compoundperiod-type-object-to-period-type-in-julia/60930/20 "2024-11-20T13:08:45Z")

</div>

Nice to see reply in this thread after 3 years 🙂

What I feel is that a large time duration becomes easier to see when it is viewed as `CompoundPeriod` type.

As example here is a `Period` (more precisely a `TimePeriod`) object `t`

```julia
julia> using Dates

julia> t = Second(115920)
115920 seconds

```

Lots of seconds right!? Looking at this time duration `t` it is difficult to imagine how long it is! This time duration exceeds a whole day or half day!? The best way to view this duration is by transforming it with larger time units (e.g. `Day`, `Hour` etc.). We can do that using `canonicalize()` function as

```julia
julia> canonicalize(t)
1 day, 8 hours, 12 minutes

```

`canonicalize()` function transforms the time duration into a visually nice `CompoundPeriod` object which helps us to understand the length of the time duration better.

Now, while doing calculations with typical time durations, it is not always convenient to work with `CompoundPeriod` objects, because it can take long time while typing out and we need to think about memory allocations also. That’s why, when necessary and possible, we need to transform the `CompoundPeriod` objects with smaller atomic units (e.g. `Minute`, `Second`, `Millisecond` etc). In `Julia v1.8.0` afterwards we can do that using `convert()` function. As we see for the `CompoundPeriod` object `cp` here

```julia
julia> cp = Day(1) + Hour(8) + Minute(12)
1 day, 8 hours, 12 minutes

julia> convert(Millisecond, cp)
115920000 milliseconds

julia> convert(Second, cp)
115920 seconds

julia> convert(Minute, cp)
1932 minutes

```
