Commit 964a86f9 authored by MichelJuillard's avatar MichelJuillard
Browse files

starting a new approach

parent b293b6c4
Pipeline #5906 failed with stage
in 35 seconds
import Dates
# Adding Semester
struct Semester <: Dates.DatePeriod
value::Int64
Semester(v::Number) = new(v)
end
# Adding periods to
for T in (:Year, :Quarter, :Month, :Week, :Day)
@eval begin
struct $T <: Dates.TimeType
instant::Dates.UTInstant{Dates.$T}
$T(instant::Dates.UTInstant{Dates.$T}) = new(instant)
end
end
end
@enum Frequency Year Semester Quarter Month Week Business Day Undated
"""
Base year used to compute the `ordinal` field of a Period type.
"""
BaseYear = 1970
"Composite type Period has fields `ordinal` and `frequency`."
struct Period <: AbstractPeriod
"""
Number of periods since year BaseYear.
"""
ordinal::Int64
"""
Frequency of the period, possible values are:
- `Year`,
- `Semester`,
- `Quarter`,
- `Month`,
- `Week`,
- `Day`, and
- `Undated` (no frequency)
"""
frequency::Frequency
end
#
# Constructors
#
"""
Period(year)
Constructor for periods with unspecified frequency.
"""
function Period(arg1::Integer)
Period(arg1, Undated)
end
"""
Period(year, frequency)
Constructor for yearly periods, if second argument's value is `Year`, or periods with unspecified frequency if
second argument's value is `Undated`.
"""
function Period(arg1::Integer, frequency::Frequency)
if frequency == Year
ordinal = arg1 - BaseYear
elseif frequency == Undated
ordinal = arg1
else
error("Frequency $frequency needs more than one argument")
end
Period(ordinal, frequency)
end
"""
Period(year, subperiod, frequency)
Constructor for bi-annual (third argument's value is `Semester`), quarterly (third argument's value is `Quarter`),
monthly (third argument's value is `Month`) or weekly (third argument's value is `Week`) periods.
"""
function Period(arg1::Integer, arg2::Integer, frequency::Frequency)
if frequency == Year
ordinal = arg1 - BaseYear
elseif frequency == Semester
@assert (arg2 in 1:2) "subperiod (semester) has to be equal to 1 or 2."
ordinal = 2*(arg1 - BaseYear) + arg2 - 1
elseif frequency == Quarter
@assert (arg2 in 1:4) "subperiod (quarter) has to be an integer between 1 and 4."
ordinal = 4*(arg1 - BaseYear) + arg2 - 1
elseif frequency == Month
@assert (arg2 in 1:12) "subperiod (month) has to be an integer between 1 and 12."
ordinal = 12*(arg1 - BaseYear) + arg2 - 1
elseif frequency == Week
@assert (arg2 <= weeksinyear(arg1)) "subperiod (week) has to be an integer between 1 and $(weeksinyear(arg1))."
ordinal = numberofweeks(arg1, arg2)
else
error("Possible values for the last argument are `Month`")
end
Period(ordinal, frequency)
end
function Period(arg1::Integer, arg2::Integer, arg3::Integer, frequency::Frequency)
if frequency == Day
return Period(arg1, arg2, arg3)
else
return Period(arg1, arg2, frequency)
end
end
Period(year::Integer, month::Integer, day::Integer) = (Date(year, month, day).instant.periods.value, Day)
Period(d::Date) = (d.instant.periods.value, Day)
"""
islongyear(y)
Return `true` if and only if year `y` has 53 ISO-8601 weeks.
# Examples
```julia-repl
julia> islongyear(2020)
true
julia> islongyear(2021)
false
```
"""
function islongyear(y::Integer)
mod(trunc(Int,y)+trunc(Int,y/4)-trunc(Int,y/100)+trunc(Int,y/400),7)==4 ||
mod(trunc(Int,y-1)+trunc(Int,(y-1)/4)-trunc(Int,(y-1)/100)+trunc(Int,(y-1)/400),7)==3
end
"""
weeksinyear(y)
Return the number of ISO-8601 weeks in year `y`.
# Examples
```julia-repl
julia> islongyear(2020)
53
julia> islongyear(2021)
52
```
"""
function weeksinyear(y::Integer)
islongyear(y) ? 53 : 52
end
"""
numberofweeks(y, w)
Return the number of ISO-8601 weeks since $BaseYear in week `w` of year `y`.
# Examples
```julia-repl
julia> islongyear(2020)
53
julia> islongyear(2021)
52
```
"""
function numberofweeks(y::Integer, w::Integer)
sum(weeksinyear.(BaseYear:(y-1)))+w
end
import Base.copy
"""
copy(p)
Return a copy of Period type p.
"""
copy(p::Period) = Period(p.ordinal, p.frequency)
import Base.:+
"""
+(p, k)
Add k subperiods to Period type p.
"""
+(p1::Period, k::Integer) = Period(p1.ordinal + k, p1.frequency)
import Base.:-
"""
+(p, k)
Substract k subperiods to Period type p.
"""
-(p1::Period, k::Integer) = Period(p1.ordinal - k, p1.frequency)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment