Skip to content

Commit 67a97c8

Browse files
committed
Make ITime(::Int,...) calculate default period
Add constructor tests
1 parent 778d1ad commit 67a97c8

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

src/ITime.jl

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,51 @@ struct ITime{INT <: Integer, DT, EPOCH <: Union{Nothing, Dates.DateTime}}
4141
end
4242

4343
"""
44-
ITime(counter::Integer; period::Dates.FixedPeriod = Dates.Second(1), epoch = nothing)
44+
ITime(counter::Integer; period::Union{Dates.FixedPeriod, Nothing}, epoch = nothing)
4545
4646
Construct an `ITime` from a counter, a period, and an optional start date.
4747
4848
If the `epoch` is provided as a `Date`, it is converted to a `DateTime`.
49+
50+
If period is not provided, the function assumes that `counter` describes a time in seconds,
51+
and attempts to find a `Dates.FixedPeriod` such that `counter` seconds can be
52+
represented as an integer multiple of that period.
53+
54+
If `counter` is zero, it defaults to a period of 1 second.
4955
"""
5056
function ITime(
5157
counter::Integer;
52-
period::Dates.FixedPeriod = Dates.Second(1),
58+
period::Union{Dates.FixedPeriod, Nothing} = nothing,
5359
epoch = nothing,
5460
)
5561
# Convert epoch to DateTime if it is not nothing (from, e.g., Date)
5662
isnothing(epoch) || (epoch = Dates.DateTime(epoch))
57-
return ITime(counter, period, epoch)
63+
if !isnothing(period)
64+
return ITime(counter, period, epoch)
65+
else
66+
counter == 0 && return ITime(counter, Dates.Second(1), epoch)
67+
potential_periods = [
68+
Dates.Week,
69+
Dates.Day,
70+
Dates.Hour,
71+
Dates.Minute,
72+
Dates.Second,
73+
Dates.Millisecond,
74+
Dates.Microsecond,
75+
Dates.Nanosecond,
76+
]
77+
for period_i in potential_periods
78+
period_ns = Dates.tons(period_i(1))
79+
t_int = 1_000_000_000 / period_ns * counter
80+
if isinteger(t_int)
81+
return ITime(
82+
typeof(counter)(div(1_000_000_000 * counter, period_ns)),
83+
period_i(1),
84+
epoch,
85+
)
86+
end
87+
end
88+
end
5889
end
5990

6091
"""

test/itime.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ using Test, Dates
5252

5353
# Cannot be represented exactly
5454
@test_throws ErrorException ITime(1e-20)
55+
56+
# Compare ITime(::Int) to ITime(::Float)
57+
function compare_itime_constructors(counter, t)
58+
a = ITime(counter)
59+
b = ITime(t)
60+
@test a.counter == b.counter
61+
@test a.period == b.period
62+
@test a.epoch == b.epoch
63+
end
64+
for nums in (0.0, 1.0, 60.0, 120.0, 3600.0)
65+
compare_itime_constructors(Int(nums), nums)
66+
end
5567
end
5668

5769
@testset "Accessors" begin

0 commit comments

Comments
 (0)