Verified Commit 94a72e5a authored by Stéphane Adjemian's avatar Stéphane Adjemian
Browse files

Fix weekly frequency.

Also added a global for the base year and unit tests.

Closes #1
parent aa63da04
# This file is machine-generated - editing it directly is not advised
[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
[[Test]]
deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
......@@ -5,3 +5,4 @@ version = "0.1.0"
[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
@enum Frequency Year Semester Quarter Month Week Business Day Undated
BaseYear = 1970
struct Period <: AbstractPeriod
ordinal::Int64
frequency::Frequency
......@@ -7,7 +9,7 @@ end
function Period(arg1::Integer, frequency::Frequency)
if frequency == Year
ordinal = arg1 - 1970
ordinal = arg1 - BaseYear
elseif frequency == Undated
ordinal = arg1
else
......@@ -18,18 +20,19 @@ end
function Period(arg1::Integer, arg2::Integer, frequency::Frequency)
if frequency == Year
ordinal = arg1 - 1970
ordinal = arg1 - BaseYear
elseif frequency == Semester
@assert(arg2 in 1:2)
ordinal = 2*(arg1 - 1970) + arg2 - 1
ordinal = 2*(arg1 - BaseYear) + arg2 - 1
elseif frequency == Quarter
@assert(arg2 in 1:4)
ordinal = 4*(arg1 - 1970) + arg2 - 1
ordinal = 4*(arg1 - BaseYear) + arg2 - 1
elseif frequency == Month
@assert(arg2 in 1:12)
ordinal = 12*(arg1 - 1970) + arg2 - 1
ordinal = 12*(arg1 - BaseYear) + arg2 - 1
elseif frequency == Week
ordinal = week1970(arg1, arg2)
@assert(arg2 <= weeksinyear(arg1))
ordinal = numberofweeks(arg1, arg2)
elseif frequency == Undated
ordinal = arg1
end
......@@ -47,6 +50,61 @@ 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::Period) = Period(p.ordinal, p.frequency)
......
# Get current directory.
rootdir0 = @__DIR__
using Test
@testset "Periods" begin
include("types.jl")
include("weeks.jl")
end
using Periods
@testset "Instantiate daily Periods" begin
@test begin
try
Periods.Period(2009,4,12)
true
catch
false
end
end
@test begin
using Dates
try
d = Date(2009,4,12)
Periods.Period(d)
true
catch
false
end
end
@test begin
using Dates
try
Periods.Period(Date(2009,4,12))[1]==Periods.Period(2009,4,12)[1]
catch
false
end
end
@test begin
using Dates
try
Periods.Period(Date(2009,4,12))[2]==Periods.Day
catch
false
end
end
@test begin
try
Periods.Period(2009,4,12)[2]==Periods.Day
catch
false
end
end
@test begin
try
Periods.Period(2009,4,32)
false
catch
true
end
end
@test begin
try
Periods.Period(2001,2,29)
false
catch
true
end
end
@test begin
try
Periods.Period(2000,2,29)
true
catch
false
end
end
end
@testset "Instantiate quarterly Periods" begin
@test begin
try
Periods.Period(2009,2,Periods.Quarter)
true
catch
false
end
end
@test begin
try
Periods.Period(2009,2,Periods.Quarter).frequency==Periods.Quarter
catch
false
end
end
@test begin
try
Periods.Period(2009,2,Periods.Quarter).ordinal::Int64
true
catch
false
end
end
@test begin
try
Periods.Period(2009,5,Periods.Quarter)
false
catch
true
end
end
end
@testset "Instantiate weekly Periods" begin
@test begin
try
Periods.Period(2009,15,Periods.Week)
true
catch
false
end
end
@test begin
try
Periods.Period(2009,15,Periods.Week).frequency==Periods.Week
catch
false
end
end
@test begin
try
Periods.Period(2009,15,Periods.Week).ordinal::Int64
true
catch
false
end
end
@test begin
try
Periods.Period(2009,54,Periods.Week)
false
catch
true
end
end
end
@testset "Instantiate monthly Periods" begin
@test begin
try
Periods.Period(2009,4,Periods.Month)
true
catch
false
end
end
@test begin
try
Periods.Period(2009,4,Periods.Month).frequency==Periods.Month
catch
false
end
end
@test begin
try
Periods.Period(2009,4,Periods.Month).ordinal::Int64
true
catch
false
end
end
@test begin
try
Periods.Period(2009,13,Periods.Month)
false
catch
true
end
end
end
@testset "Instantiate bi-annual Periods" begin
@test begin
try
Periods.Period(2009,1,Periods.Semester)
true
catch
false
end
end
@test begin
try
Periods.Period(2009,1,Periods.Semester).frequency==Periods.Semester
catch
false
end
end
@test begin
try
Periods.Period(2009,1,Periods.Semester).ordinal::Int64
true
catch
false
end
end
@test begin
try
Periods.Period(2009,3,Periods.Semester)
false
catch
true
end
end
end
@testset "Instantiate annual Periods" begin
@test begin
try
Periods.Period(2009,Periods.Year)
true
catch
false
end
end
@test begin
try
Periods.Period(2009,Periods.Year).frequency==Periods.Year
catch
false
end
end
@test begin
try
Periods.Period(2009,Periods.Year).ordinal::Int64
true
catch
false
end
end
end
# Taken from https://en.wikipedia.org/wiki/ISO_week_date (Long years per 400-year leap-cycle)
LongYears = [4; 9 ; 15 ; 20 ; 26 ; 32 ; 37 ; 43 ; 48 ; 54 ; 60 ; 65 ; 71 ; 76 ; 82 ; 88 ; 93 ; 99 ;
105 ; 111 ; 116 ; 122 ; 128 ; 133 ; 139 ; 144 ; 150 ; 156 ; 161 ; 167 ; 172 ; 178 ; 184 ; 189 ; 195 ;
201 ; 207 ; 212 ; 218 ; 224 ; 229 ; 235 ; 240 ; 246 ; 252 ; 257 ; 263 ; 268 ; 274 ; 280 ; 285 ; 291 ; 296 ;
303 ; 308 ; 314 ; 320 ; 325 ; 331 ; 336 ; 342 ; 348 ; 353 ; 359 ; 364 ; 370 ; 376 ; 381 ; 387 ; 392 ; 398]
@testset "Long weeks (ISO-8601)" begin
@test begin
try
Periods.islongyear(2020)
catch
false
end
end
@test begin
try
!Periods.islongyear(2021)
catch
false
end
end
@test begin
try
all(Periods.islongyear.(LongYears))
catch
false
end
end
@test begin
try
Periods.weeksinyear(2020)==53
catch
false
end
end
@test begin
try
Periods.weeksinyear(2021)==52
catch
false
end
end
@test begin
try
all(Periods.weeksinyear.(LongYears).==53)
catch
false
end
end
@test begin
try
all(Periods.weeksinyear.(setdiff(1:400,LongYears)).==52)
catch
false
end
end
end
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