# How to Print/Parse a TimePeriod with a Specific Format?

**URL:** <https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322>\
**Category:** General Usage\
**Tags:** dates, timeperiod\
**Created:** [March 23, 2022, 9:58am UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322 "2022-03-23T09:58:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)\
**Post date:** [March 23, 2022, 9:58am UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/1 "2022-03-23T09:58:54Z")

</div>

Hi!

I want to parse and print durations in the format `"HH:MM:SS.sss"`. Parsing seems to be pretty simple. if I do for example

```julia
julia> str = "1:02:23.234"
"1:02:23.234"
julia> t = Time(str)
01:02:23.234

```

this seems to work just fine. However, this is not a `TimePeriod` but a time.

If I want to go the other way and print `TimePeriods` in that format I’m running into problems:

```julia
julia> Dates.format(Time(Second(32)), "HH:MM:SS.sss")
"00:00:32.000"

```

works fine but

```julia
julia> Dates.format(Time(Second(432)), "HH:MM:SS.sss")
ERROR: ArgumentError: Second: 432 out of range (0:59)

```

throws an error. `Dates.format` does not take `TimePeriod`s for an argument:

```julia
julia> Dates.format(Second(432), "HH:MM:SS.sss")
ERROR: MethodError: no method matching format(::Second, ::String)

```

Working with `CompoundPeriod`s also does not work:

```julia
julia> d = Minute(2) + Second(10)
2 minutes, 10 seconds

julia> Dates.format(Time(d), "HH:MM:SS.sss")
ERROR: MethodError: no method matching Int64(::Dates.CompoundPeriod)

```

Does anyone know if there’s a built in way to print my duration in the desired format, is there any package that deals with this, or do I have to write a custom function?

---

<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:** [March 23, 2022, 10:35am UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/2 "2022-03-23T10:35:37Z")

</div>

You can use `Time(0) + Second(…)` instead of `Time(Second(…))`:

```julia
julia> Time(0) + Second(432)
00:07:12

julia> Dates.format(Time(0) + Second(432), "HH:MM:SS.sss")
"00:07:12.000"

```

---

<div class="post-metadata">

**Author:** ![MLackner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlackner/32/2789_2.png) [@MLackner](https://discourse.julialang.org/u/MLackner)\
**Post date:** [March 23, 2022, 10:43am UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/3 "2022-03-23T10:43:45Z")

</div>

That’s it! Thanks! 🙂

---

<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:** [March 23, 2022, 10:45am UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/4 "2022-03-23T10:45:01Z")

</div>

> [@MLackner](#):
>
> Working with CompoundPeriods also does not work:

Actually, using the `CompoundPeriods` package it does:

```julia
using Dates, CompoundPeriods
d = Minute(2) + Second(10)
Dates.format(Time(d), "HH:MM:SS.sss")
"00:02:10.000"

```

---

<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 24, 2024, 12:27pm UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/5 "2024-10-24T12:27:05Z")

</div>

> [@sostock](#):
>
> You can use `Time(0) + Second(…)` instead of `Time(Second(…))`:

There is an easier (more elegant?) solution.

- You have to know that only `Time`, `Date` and `DateTime` types are printable (aka `format`able)

Once you know this, you convert to one of these types. In your case, you want to convert to a `Time` type using the constructor function `Dates.Time(...)`.

So do something like this

```julia
using Dates
d = Minute(2) + Second(10)
println(typeof(d)) # Dates.CompoundPeriod

time = Dates.Time(canonicalize(Dates.CompoundPeriod(d)).periods...)
time_str::String = Dates.format(time, "HH:MM:SS")
println("$(time_str)")

```

The “special sauce” here is twofold

- `canonicalize` converts any `CompoundPeriod` to the canonical form, the trick here being to created it from the splayed `.periods` field (this is what the `d.periods...` is about
- you can then create a `Time` object from this `CompountPeriod` object

---

<div class="post-metadata">

**Author:** ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)\
**Post date:** [January 25, 2026, 5:42pm UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/6 "2026-01-25T17:42:29Z")

</div>

This doesn’t work for periods longer than a day:

```julia
julia> using Dates

julia> myformat(sec::Dates.Second, fmt::AbstractString) = Dates.Time(Dates.canonicalize(sec).periods...);

julia> myformat(Second(500), "HH:MM:SS")
00:08:20

julia> myformat(Second(5000), "HH:MM:SS")
01:23:20

julia> myformat(Second(50000), "HH:MM:SS")
13:53:20

julia> myformat(Second(500000), "HH:MM:SS")
ERROR: MethodError: no method matching Int64(::Day)
The type `Int64` exists, but no method is defined for this combination of argument types when trying to construct it.

Closest candidates are:
  Int64(::Float64)
   @ Base float.jl:919
  Int64(::Float32)
   @ Base float.jl:919
  Int64(::Float16)
   @ Base float.jl:919
  ...

Stacktrace:
 [1] Time(h::Day, mi::Hour, s::Minute, ms::Second, us::Int64, ns::Int64, ampm::Dates.AMPM)
   @ Dates ~/.julia/juliaup/julia-1.12.4+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Dates/src/types.jl:423
 [2] myformat(sec::Second, fmt::String)
   @ Main ./REPL[2]:1
 [3] top-level scope
   @ REPL[6]:1

```

Meanwhile Python has no problem printing large time periods:

```python
>>> from datetime import timedelta
>>> str(timedelta(seconds=800000000.9))
'9259 days, 6:13:20.900000'

```

(However, “9259 days” makes no sense; at this point it should be split into weeks, months and years)

* * *

Using nanoseconds doesn’t work either:

```julia
julia> using Dates

julia> begin
               myformat(period::Dates.TimePeriod, fmt::AbstractString) =
                       Dates.Time(Dates.canonicalize(period).periods...)
               myformat(sec::Real, fmt::AbstractString) =
                       myformat(Dates.Nanosecond(round(Int, sec * 1e9)), fmt)
       end;

julia> myformat(100306.25350200786, "HH:MM:SS")
ERROR: MethodError: no method matching Time(::Day, ::Hour, ::Minute, ::Second, ::Millisecond, ::Microsecond, ::Nanosecond)
The type `Time` exists, but no method is defined for this combination of argument types when trying to construct it.

Closest candidates are:
  Time(::TimePeriod, ::TimePeriod...)
   @ Dates ~/.julia/juliaup/julia-1.12.4+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Dates/src/types.jl:378
  Time(::Any, ::Any, ::Any, ::Any, ::Any, ::Any)
   @ Dates ~/.julia/juliaup/julia-1.12.4+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Dates/src/types.jl:423
  Time(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Dates.AMPM)
   @ Dates ~/.julia/juliaup/julia-1.12.4+0.aarch64.apple.darwin14/share/julia/stdlib/v1.12/Dates/src/types.jl:423
  ...

Stacktrace:
 [1] myformat
   @ ./REPL[3]:2 [inlined]
 [2] myformat(sec::Float64, fmt::String)
   @ Main ./REPL[3]:4
 [3] top-level scope
   @ REPL[13]:1

```

Apparently `Day` is not a `TimePeriod`:

```julia
julia> Day <: TimePeriod
false

```

…which is why [`Time(period::TimePeriod, periods::TimePeriod...)`](https://github.com/JuliaLang/julia/blob/8dab3f0623e1bf75035aa48f2f8380a11b22306d/stdlib/Dates/src/types.jl#L378) is not called. Instead, [`Time(h, mi=0, s=0, ms=0, us=0, ns=0, ampm::AMPM=TWENTYFOURHOUR)`](https://github.com/JuliaLang/julia/blob/8dab3f0623e1bf75035aa48f2f8380a11b22306d/stdlib/Dates/src/types.jl#L423) is called.

If `Day` is not a `TimePeriod`, what is it, then??? Same for `Week`, `Month`, etc: are they not time periods?

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [January 25, 2026, 7:48pm UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/7 "2026-01-25T19:48:36Z")

</div>

```julia-auto
julia> supertypes(Day)

(Day, DatePeriod, Period, Dates.AbstractTime, Any)

julia> subtypes(Dates.AbstractTime)
5-element Vector{Any}:
 Dates.Calendar
 Dates.CompoundPeriod
 Dates.Instant
 Period
 TimeType

julia> subtypes(Period)
2-element Vector{Any}:
 DatePeriod
 TimePeriod

julia> supertypes(Week)
(Week, DatePeriod, Period, Dates.AbstractTime, Any)

julia> supertypes(Month)
(Month, DatePeriod, Period, Dates.AbstractTime, Any)

```

---

<div class="post-metadata">

**Author:** ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)\
**Post date:** [January 25, 2026, 8:21pm UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/8 "2026-01-25T20:21:18Z")

</div>

I know, those were rhetorical questions. I was trying to say that _all of them_ are time periods.

What I don’t understand is two things:

1. Why is there “no method matching `format(::Dates.CompoundPeriod, ::String)`”? Why can I not format `CompoundPeriod`s? The default string representation is too long, like `82673 weeks, 4 days, 2 hours, 56 minutes, 20 seconds` (why does it not go further, to months and years? I cannot immediately comprehend how long 82673 weeks is)
2. Why is it not possible to have fractional seconds/minutes/etc? `Second(1.234)` gives `InexactError: Int64(1.234)`. Sure, but now I have to go convert this to nanoseconds, round that to an integer, then call `canonicalize`, only to face the inability to have custom formats for `Dates.CompoundPeriod`…

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [January 25, 2026, 9:13pm UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/9 "2026-01-25T21:13:50Z")

</div>

> [@ForceBru](#):
>
> (why does it not go further, to months and years? I cannot immediately comprehend how long 82673 weeks is)

Because months and years are variable length, and it does not have the context of the absolute date to give an accurate count of months or years.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 26, 2026, 3:41am UTC](https://discourse.julialang.org/t/how-to-print-parse-a-timeperiod-with-a-specific-format/78322/10 "2026-01-26T03:41:12Z")

</div>

> [@ForceBru](#):
>
> Why is it not possible to have fractional seconds/minutes/etc?

This was a design decision that was made early on, which is somewhat controversial but is difficult to change. See the long discussion in [`DateTime` arithmetic on `Microsecond` (or smaller) scale](https://discourse.julialang.org/t/datetime-arithmetic-on-microsecond-or-smaller-scale/102949)
