@@ -41,20 +41,51 @@ struct ITime{INT <: Integer, DT, EPOCH <: Union{Nothing, Dates.DateTime}}
41
41
end
42
42
43
43
"""
44
- ITime(counter::Integer; period::Dates.FixedPeriod = Dates.Second(1) , epoch = nothing)
44
+ ITime(counter::Integer; period::Union{ Dates.FixedPeriod, Nothing} , epoch = nothing)
45
45
46
46
Construct an `ITime` from a counter, a period, and an optional start date.
47
47
48
48
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.
49
55
"""
50
56
function ITime (
51
57
counter:: Integer ;
52
- period:: Dates.FixedPeriod = Dates . Second ( 1 ) ,
58
+ period:: Union{ Dates.FixedPeriod, Nothing} = nothing ,
53
59
epoch = nothing ,
54
60
)
55
61
# Convert epoch to DateTime if it is not nothing (from, e.g., Date)
56
62
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
58
89
end
59
90
60
91
"""
0 commit comments