Best way to infer precision for periods (Date)

dates
development

#1

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?


#2

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.


#3

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