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