Given an AbstractVector{T} where T <: Dates.AbstractTime
what would be a good way to infer the precision of the dates/times?
For example, consider
obj = Date("2000"):Dates.Year(1):Date("2009")
when first differencing the data one gets,
distance = diff(obj)
9-element Vector{Base.Dates.Day}:
366 days
365 days
365 days
365 days
366 days
365 days
365 days
365 days
366 days
The ideal solution would be to get Dates.Year(1)
. My current approach is the following,
minimum(filter(elem -> elem > zero(Dates.Nanosecond),
first.(getfield.(Dates.canonicalize.(
Dates.CompoundPeriod.(diff(obj))), :periods))))
52 weeks
Hence I am able to get rid of the noise (being off by 1 - 2 days) and get a good measure of the frequency. For trimesters I get around 12 weeks
and for biannual frequency 25 weeks
. Is there a better method for inferring frequency / precision?
@quinnj was there development of a related feature?
I think the question is not well-defined, since Date(2000)
is equivalent to Date(2000, 1, 1)
. Given the object, Julia cannot infer that the month and day were filled in as defaults, so the precision is a day as for other dates.
The best solution may be using floor
, ceil
, or round
, depending on what you want.
Ended up implementing the following solution.
function frequency(obj::AbstractVector{T}) where T <: Dates.Date
FirstDifference = diff(obj)
FormalFirstDifference = Dates.canonicalize.(Dates.CompoundPeriod.(FirstDifference))
if all(length.(getfield.(FormalFirstDifference, :periods)) .== 1)
output = Dates.CompoundPeriod(minimum(FirstDifference))
output = Dates.canonicalize(output)
else
output = diff(map(ymd -> [12 * ymd[1] + ymd[2], ymd[3]], Dates.yearmonthday.(obj)))
if all(getindex.(output, 2) .== 0)
output = minimum(reduce(vcat, first.(output)))
output = Dates.canonicalize(Dates.CompoundPeriod(Dates.Month(output)))
else
output = Dates.CompoundPeriod(minimum(FirstDifference))
end
end
return output
end