From 03bee90c88a2602856c2801e76395d38678d2634 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Thu, 3 Nov 2016 16:58:37 +0000 Subject: [PATCH 1/2] * Make `DayOfWeek` an `Enum`, deprecate `dayofweek`. (#19210) * Provide optional argument to `firsdayofweek`/`lastdayofweek` (#19208) * A few misc fixes. --- base/dates/Dates.jl | 2 +- base/dates/accessors.jl | 7 ++++ base/dates/adjusters.jl | 66 ++++++++++++++++-------------------- base/dates/io.jl | 4 +-- base/dates/query.jl | 75 ++++++++++++++++++++++++----------------- base/deprecated.jl | 16 +++++++++ doc/stdlib/dates.rst | 45 ++++++++++++++++++------- test/dates/adjusters.jl | 39 +++++++++++---------- test/dates/query.jl | 22 ++++++------ 9 files changed, 164 insertions(+), 112 deletions(-) diff --git a/base/dates/Dates.jl b/base/dates/Dates.jl index ad620d10125d4..9dea813cde908 100644 --- a/base/dates/Dates.jl +++ b/base/dates/Dates.jl @@ -24,7 +24,7 @@ export Period, DatePeriod, TimePeriod, yearmonthday, yearmonth, monthday, year, month, week, day, hour, minute, second, millisecond, dayofmonth, # query.jl - dayofweek, isleapyear, daysinmonth, daysinyear, dayofyear, dayname, dayabbr, + DayOfWeek, isleapyear, daysinmonth, daysinyear, dayofyear, dayname, dayabbr, dayofweekofmonth, daysofweekinmonth, monthname, monthabbr, quarterofyear, dayofquarter, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, diff --git a/base/dates/accessors.jl b/base/dates/accessors.jl index 71441a1e6fe6c..9d289b9d2f50c 100644 --- a/base/dates/accessors.jl +++ b/base/dates/accessors.jl @@ -42,8 +42,15 @@ end # Accessor functions value(dt::TimeType) = dt.instant.periods.value + +""" + days(dt::TimeType) -> Int64 + +The Rata Die day number: the number of days since `Date("0000-12-31")`. +""" days(dt::Date) = value(dt) days(dt::DateTime) = fld(value(dt),86400000) + year(dt::TimeType) = year(days(dt)) month(dt::TimeType) = month(days(dt)) week(dt::TimeType) = week(days(dt)) diff --git a/base/dates/adjusters.jl b/base/dates/adjusters.jl index 68929ed25e8d6..eaed3dd177599 100644 --- a/base/dates/adjusters.jl +++ b/base/dates/adjusters.jl @@ -23,24 +23,26 @@ Dates.trunc(::Dates.TimeType, ::Type{Dates.Period}) # Adjusters """ - firstdayofweek(dt::TimeType) -> TimeType + firstdayofweek(dt::TimeType[, firstday::DayOfWeek=Monday]) -> TimeType -Adjusts `dt` to the Monday of its week. +Adjusts `dt` to the first day of its week. The optional second argument specifies the +`DayOfWeek` which starts the week: by default, this is `Monday`, as per ISO 8601. """ function firstdayofweek end -firstdayofweek(dt::Date) = Date(UTD(value(dt) - dayofweek(dt) + 1)) -firstdayofweek(dt::DateTime) = DateTime(firstdayofweek(Date(dt))) +firstdayofweek(dt::Date, firstday::DayOfWeek=Monday) = dt - Day(mod(Int(DayOfWeek(dt)) - Int(firstday),7)) +firstdayofweek(dt::DateTime, firstday::DayOfWeek=Monday) = DateTime(firstdayofweek(Date(dt),firstday)) """ - lastdayofweek(dt::TimeType) -> TimeType + lastdayofweek(dt::TimeType[, lastday::DayOfWeek=Sunday]) -> TimeType -Adjusts `dt` to the Sunday of its week. +Adjusts `dt` to the last day of its week. The optional second argument specifies the +`DayOfWeek` which ends the week: by default, this is `Sunday`, as per ISO 8601. """ function lastdayofweek end -lastdayofweek(dt::Date) = Date(UTD(value(dt) + (7 - dayofweek(dt)))) -lastdayofweek(dt::DateTime) = DateTime(lastdayofweek(Date(dt))) +lastdayofweek(dt::Date, lastday::DayOfWeek=Sunday) = dt + Day(mod(Int(lastday) - Int(DayOfWeek(dt)),7)) +lastdayofweek(dt::DateTime, lastday::DayOfWeek=Sunday) = DateTime(lastdayofweek(Date(dt),lastday)) """ firstdayofmonth(dt::TimeType) -> TimeType @@ -49,7 +51,7 @@ Adjusts `dt` to the first day of its month. """ function firstdayofmonth end -firstdayofmonth(dt::Date) = Date(UTD(value(dt) - day(dt) + 1)) +firstdayofmonth(dt::Date) = dt - Day(dayofmonth(dt) - 1) firstdayofmonth(dt::DateTime) = DateTime(firstdayofmonth(Date(dt))) """ @@ -61,7 +63,7 @@ function lastdayofmonth end function lastdayofmonth(dt::Date) y, m, d = yearmonthday(dt) - return Date(UTD(value(dt) + daysinmonth(y, m) - d)) + return dt + Day(daysinmonth(y, m) - d) end lastdayofmonth(dt::DateTime) = DateTime(lastdayofmonth(Date(dt))) @@ -72,7 +74,7 @@ Adjusts `dt` to the first day of its year. """ function firstdayofyear end -firstdayofyear(dt::Date) = Date(UTD(value(dt) - dayofyear(dt) + 1)) +firstdayofyear(dt::Date) = dt - Day(dayofyear(dt) - 1) firstdayofyear(dt::DateTime) = DateTime(firstdayofyear(Date(dt))) """ @@ -84,7 +86,7 @@ function lastdayofyear end function lastdayofyear(dt::Date) y, m, d = yearmonthday(dt) - return Date(UTD(value(dt) + daysinyear(y) - dayofyear(y, m, d))) + return dt + Day(daysinyear(y) - dayofyear(y, m, d)) end lastdayofyear(dt::DateTime) = DateTime(lastdayofyear(Date(dt))) @@ -184,24 +186,14 @@ function DateTime(func::Function, y, m, d, h, mi, s; step::Period=Millisecond(1) return adjust(DateFunction(func, negate, DateTime(y)), DateTime(y, m, d, h, mi, s), step, limit) end -# Return the next TimeType that falls on dow -ISDAYOFWEEK = Dict(Mon => DateFunction(ismonday, false, Date(0)), - Tue => DateFunction(istuesday, false, Date(0)), - Wed => DateFunction(iswednesday, false, Date(0)), - Thu => DateFunction(isthursday, false, Date(0)), - Fri => DateFunction(isfriday, false, Date(0)), - Sat => DateFunction(issaturday, false, Date(0)), - Sun => DateFunction(issunday, false, Date(0))) - # "same" indicates whether the current date can be considered or not """ - tonext(dt::TimeType,dow::Int;same::Bool=false) -> TimeType + tonext(dt::TimeType, dow::DayOfWeek; same::Bool=false) -> TimeType -Adjusts `dt` to the next day of week corresponding to `dow` with `1 = Monday, 2 = Tuesday, -etc`. Setting `same=true` allows the current `dt` to be considered as the next `dow`, -allowing for no adjustment to occur. +Adjusts `dt` to the next day of week corresponding to `dow`. Setting `same=true` allows +the current `dt` to be considered as the next `dow`, allowing for no adjustment to occur. """ -tonext(dt::TimeType, dow::Int; same::Bool=false) = adjust(ISDAYOFWEEK[dow], same ? dt : dt+Day(1), Day(1), 7) +tonext(dt::TimeType, dow::DayOfWeek; same::Bool=false) = lastdayofweek(same ? dt : dt+Day(1), dow) # Return the next TimeType where func evals true using step in incrementing """ @@ -217,13 +209,13 @@ function tonext(func::Function, dt::TimeType;step::Period=Day(1), negate::Bool=f end """ - toprev(dt::TimeType,dow::Int;same::Bool=false) -> TimeType + toprev(dt::TimeType, dow::DayOfWeek; same::Bool=false) -> TimeType -Adjusts `dt` to the previous day of week corresponding to `dow` with `1 = Monday, 2 = -Tuesday, etc`. Setting `same=true` allows the current `dt` to be considered as the previous -`dow`, allowing for no adjustment to occur. +Adjusts `dt` to the previous day of week corresponding to `dow`. Setting `same=true` +allows the current `dt` to be considered as the previous `dow`, allowing for no adjustment +to occur. """ -toprev(dt::TimeType, dow::Int; same::Bool=false) = adjust(ISDAYOFWEEK[dow], same ? dt : dt+Day(-1), Day(-1), 7) +toprev(dt::TimeType, dow::DayOfWeek; same::Bool=false) = firstdayofweek(same ? dt : dt-Day(1), dow) """ toprev(func::Function,dt::TimeType;step=Day(-1),negate=false,limit=10000,same=false) -> TimeType @@ -239,24 +231,24 @@ end # Return the first TimeType that falls on dow in the Month or Year """ - tofirst(dt::TimeType,dow::Int;of=Month) -> TimeType + tofirst(dt::TimeType, dow::DayOfWeek; of=Month) -> TimeType Adjusts `dt` to the first `dow` of its month. Alternatively, `of=Year` will adjust to the first `dow` of the year. """ -function tofirst(dt::TimeType, dow::Int; of::Union{Type{Year}, Type{Month}}=Month) +function tofirst(dt::TimeType, dow::DayOfWeek; of::Union{Type{Year}, Type{Month}}=Month) dt = of <: Month ? firstdayofmonth(dt) : firstdayofyear(dt) - return adjust(ISDAYOFWEEK[dow], dt, Day(1), 366) + lastdayofweek(dt, dow) end # Return the last TimeType that falls on dow in the Month or Year """ - tolast(dt::TimeType,dow::Int;of=Month) -> TimeType + tolast(dt::TimeType, dow::DayOfWeek; of=Month) -> TimeType Adjusts `dt` to the last `dow` of its month. Alternatively, `of=Year` will adjust to the last `dow` of the year. """ -function tolast(dt::TimeType, dow::Int; of::Union{Type{Year}, Type{Month}}=Month) +function tolast(dt::TimeType, dow::DayOfWeek; of::Union{Type{Year}, Type{Month}}=Month) dt = of <: Month ? lastdayofmonth(dt) : lastdayofyear(dt) - return adjust(ISDAYOFWEEK[dow], dt, Day(-1), 366) + firstdayofweek(dt, dow) end diff --git a/base/dates/io.jl b/base/dates/io.jl index f482502eafe50..f6d2da5c8f733 100644 --- a/base/dates/io.jl +++ b/base/dates/io.jl @@ -204,9 +204,9 @@ function slotformat(slot::Slot{Month},dt,locale) end function slotformat(slot::Slot{DayOfWeekSlot},dt,locale) if slot.letter == 'e' - return VALUETODAYOFWEEKABBR[locale][dayofweek(dt)] + return VALUETODAYOFWEEKABBR[locale][DayOfWeek(dt)] else # == 'E' - return VALUETODAYOFWEEK[locale][dayofweek(dt)] + return VALUETODAYOFWEEK[locale][DayOfWeek(dt)] end end slotformat(slot::Slot{Millisecond},dt,locale) = rpad(string(millisecond(dt)/1000.0)[3:end], slot.width, "0") diff --git a/base/dates/query.jl b/base/dates/query.jl index 8524dec97972f..f374f4d8a1465 100644 --- a/base/dates/query.jl +++ b/base/dates/query.jl @@ -4,9 +4,6 @@ ### Core query functions -# Monday = 1....Sunday = 7 -dayofweek(days) = mod1(days,7) - # Number of days in year """ daysinyear(dt::TimeType) -> Int @@ -20,30 +17,39 @@ const MONTHDAYS = [0,31,59,90,120,151,181,212,243,273,304,334] dayofyear(y,m,d) = MONTHDAYS[m] + d + (m > 2 && isleapyear(y)) ### Days of the Week -""" - dayofweek(dt::TimeType) -> Int64 +@enum DayOfWeek Monday=1 Tuesday=2 Wednesday=3 Thursday=4 Friday=5 Saturday=6 Sunday=7 -Returns the day of the week as an `Int64` with `1 = Monday, 2 = Tuesday, etc.`. """ -dayofweek(dt::TimeType) = dayofweek(days(dt)) + DayOfWeek(n::Integer) -const Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday = 1,2,3,4,5,6,7 -const Mon,Tue,Wed,Thu,Fri,Sat,Sun = 1,2,3,4,5,6,7 -const english_daysofweek = Dict(1=>"Monday",2=>"Tuesday",3=>"Wednesday", - 4=>"Thursday",5=>"Friday",6=>"Saturday",7=>"Sunday") -const VALUETODAYOFWEEK = Dict{String,Dict{Int,String}}("english"=>english_daysofweek) -const english_daysofweekabbr = Dict(1=>"Mon",2=>"Tue",3=>"Wed", - 4=>"Thu",5=>"Fri",6=>"Sat",7=>"Sun") -const VALUETODAYOFWEEKABBR = Dict{String,Dict{Int,String}}("english"=>english_daysofweekabbr) -dayname(dt::Integer;locale::AbstractString="english") = VALUETODAYOFWEEK[locale][dt] +An `Enum` with `DayOfWeek(1) == Monday`, `DayOfWeek(2) == Tuesday`, etc. Accepts an +arbitrary-sized integer, from which days will be computed modulo 7. +```jldoctest +julia> DayOfWeek(8) == Monday +true +``` """ - dayabbr(dt::TimeType; locale="english") -> AbstractString +DayOfWeek(n::Integer) = convert(DayOfWeek, mod1(n, 7)) -Return the abbreviated name corresponding to the day of the week of the `Date` or `DateTime` -in the given `locale`. """ -dayabbr(dt::Integer;locale::AbstractString="english") = VALUETODAYOFWEEKABBR[locale][dt] + DayOfWeek(dt::TimeType) + +Returns the day of the week of `dt` as an element of the enum `DayOfWeek`. +""" +DayOfWeek(dt::TimeType) = DayOfWeek(days(dt)) + + +const Mon,Tue,Wed,Thu,Fri,Sat,Sun = Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday + +const english_daysofweek = Dict(k => string(k) for k in instances(DayOfWeek)) +const VALUETODAYOFWEEK = Dict{String,Dict{DayOfWeek,String}}("english"=>english_daysofweek) + +const english_daysofweekabbr = Dict(k => string(k)[1:3] for k in instances(DayOfWeek)) +const VALUETODAYOFWEEKABBR = Dict{String,Dict{DayOfWeek,String}}("english"=>english_daysofweekabbr) + +dayname(dow::DayOfWeek;locale::AbstractString="english") = VALUETODAYOFWEEK[locale][dow] +dayabbr(dow::DayOfWeek;locale::AbstractString="english") = VALUETODAYOFWEEKABBR[locale][dow] """ dayname(dt::TimeType; locale="english") -> AbstractString @@ -51,18 +57,24 @@ dayabbr(dt::Integer;locale::AbstractString="english") = VALUETODAYOFWEEKABBR[loc Return the full day name corresponding to the day of the week of the `Date` or `DateTime` in the given `locale`. """ -dayname(dt::TimeType;locale::AbstractString="english") = VALUETODAYOFWEEK[locale][dayofweek(dt)] +dayname(dt::TimeType;locale::AbstractString="english") = VALUETODAYOFWEEK[locale][DayOfWeek(dt)] -dayabbr(dt::TimeType;locale::AbstractString="english") = VALUETODAYOFWEEKABBR[locale][dayofweek(dt)] +""" + dayabbr(dt::TimeType; locale="english") -> AbstractString + +Return the abbreviated name corresponding to the day of the week of the `Date` or `DateTime` +in the given `locale`. +""" +dayabbr(dt::TimeType;locale::AbstractString="english") = VALUETODAYOFWEEKABBR[locale][DayOfWeek(dt)] # Convenience methods for each day -ismonday(dt::TimeType) = dayofweek(dt) == Mon -istuesday(dt::TimeType) = dayofweek(dt) == Tue -iswednesday(dt::TimeType) = dayofweek(dt) == Wed -isthursday(dt::TimeType) = dayofweek(dt) == Thu -isfriday(dt::TimeType) = dayofweek(dt) == Fri -issaturday(dt::TimeType) = dayofweek(dt) == Sat -issunday(dt::TimeType) = dayofweek(dt) == Sun +ismonday(dt::TimeType) = DayOfWeek(dt) == Mon +istuesday(dt::TimeType) = DayOfWeek(dt) == Tue +iswednesday(dt::TimeType) = DayOfWeek(dt) == Wed +isthursday(dt::TimeType) = DayOfWeek(dt) == Thu +isfriday(dt::TimeType) = DayOfWeek(dt) == Fri +issaturday(dt::TimeType) = DayOfWeek(dt) == Sat +issunday(dt::TimeType) = DayOfWeek(dt) == Sun # i.e. 1st Monday? 2nd Monday? 3rd Wednesday? 5th Sunday? """ @@ -71,9 +83,10 @@ issunday(dt::TimeType) = dayofweek(dt) == Sun For the day of week of `dt`, returns which number it is in `dt`'s month. So if the day of the week of `dt` is Monday, then `1 = First Monday of the month, 2 = Second Monday of the month, etc.` In the range 1:5. + +See also `daysofweekinmonth`. """ -dayofweekofmonth(dt::TimeType) = (d = day(dt); return d < 8 ? 1 : - d < 15 ? 2 : d < 22 ? 3 : d < 29 ? 4 : 5) +dayofweekofmonth(dt::TimeType) = fld1(dayofmonth(dt), 7) # Total number of a day of week in the month # e.g. are there 4 or 5 Mondays in this month? diff --git a/base/deprecated.jl b/base/deprecated.jl index 27ff73bde9b09..dac180b1dcf81 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1127,6 +1127,22 @@ eval(Base.Dates, quote end end recur{T<:TimeType}(fun::Function, start::T, stop::T; step::Period=Day(1), negate::Bool=false, limit::Int=10000) = recur(fun, start:step:stop; negate=negate) + +# #19212 +eval(Base.Dates,quote + @deprecate(dayofweek(dt), Int64(DayOfWeek(dt))) + @deprecate(tonext(dt::TimeType, dow::Int; same::Bool=false), + tonext(dt, DayOfWeek(dow); same=same)) + @deprecate(toprev(dt::TimeType, dow::Int; same::Bool=false), + toprev(dt, DayOfWeek(dow); same=same)) + @deprecate(tofirst(dt::TimeType, dow::Int; of::Union{Type{Year}, Type{Month}}=Month), + tofirst(dt, DayOfWeek(dow); same=same)) + @deprecate(tolast(dt::TimeType, dow::Int; of::Union{Type{Year}, Type{Month}}=Month), + tolast(dt, DayOfWeek(dow); same=same)) + @deprecate(dayname(dt::Integer;locale::AbstractString="english"), + dayname(DayOfWeek(dt); locale=locale)) + @deprecate(dayabbr(dt::Integer;locale::AbstractString="english"), + dayabbr(DayOfWeek(dt); locale=locale)) end) # End deprecations scheduled for 0.6 diff --git a/doc/stdlib/dates.rst b/doc/stdlib/dates.rst index 78a2af3dd68e4..9ee60d0dbc0f4 100644 --- a/doc/stdlib/dates.rst +++ b/doc/stdlib/dates.rst @@ -61,7 +61,7 @@ Dates Functions --------------- All Dates functions are defined in the ``Dates`` module; note that only the ``Date``, ``DateTime``, and ``now`` functions are exported; -to use all other ``Dates`` functions, you'll need to prefix each function call with an explicit ``Dates.``, e.g. ``Dates.dayofweek(dt)``. +to use all other ``Dates`` functions, you'll need to prefix each function call with an explicit ``Dates.``, e.g. ``Dates.DayOfWeek(dt)``. Alternatively, you can write ``using Base.Dates`` to bring all exported functions into ``Main`` to be used without the ``Dates.`` prefix. @@ -263,6 +263,12 @@ Accessor Functions The day of month of a ``Date`` or ``DateTime`` as an ``Int64``\ . +.. function:: days(dt::TimeType) -> Int64 + + .. Docstring generated from Julia source + + The Rata Die day number: the number of days since ``Date("0000-12-31")``\ . + .. function:: hour(dt::DateTime) -> Int64 .. Docstring generated from Julia source @@ -368,11 +374,22 @@ Query Functions Return the abbreviated name corresponding to the day of the week of the ``Date`` or ``DateTime`` in the given ``locale``\ . -.. function:: dayofweek(dt::TimeType) -> Int64 +.. function:: DayOfWeek(n::Integer) + + .. Docstring generated from Julia source + + An ``Enum`` with ``DayOfWeek(1) == Monday``\ , ``DayOfWeek(2) == Tuesday``\ , etc. Accepts an arbitrary-sized integer, from which days will be computed modulo 7. + + .. doctest:: + + julia> DayOfWeek(8) == Monday + true + +.. function:: DayOfWeek(dt::TimeType) .. Docstring generated from Julia source - Returns the day of the week as an ``Int64`` with ``1 = Monday, 2 = Tuesday, etc.``\ . + Returns the day of the week of ``dt`` as an element of the enum ``DayOfWeek``\ . .. function:: dayofmonth(dt::TimeType) -> Int64 @@ -386,6 +403,8 @@ Query Functions For the day of week of ``dt``\ , returns which number it is in ``dt``\ 's month. So if the day of the week of ``dt`` is Monday, then ``1 = First Monday of the month, 2 = Second Monday of the month, etc.`` In the range 1:5. + See also ``daysofweekinmonth``\ . + .. function:: daysofweekinmonth(dt::TimeType) -> Int .. Docstring generated from Julia source @@ -449,17 +468,17 @@ Adjuster Functions Truncates the value of ``dt`` according to the provided ``Period`` type. E.g. if ``dt`` is ``1996-01-01T12:30:00``\ , then ``trunc(dt,Day) == 1996-01-01T00:00:00``\ . -.. function:: firstdayofweek(dt::TimeType) -> TimeType +.. function:: firstdayofweek(dt::TimeType[, firstday::DayOfWeek=Monday]) -> TimeType .. Docstring generated from Julia source - Adjusts ``dt`` to the Monday of its week. + Adjusts ``dt`` to the first day of its week. The optional second argument specifies the ``DayOfWeek`` which starts the week: by default, this is ``Monday``\ , as per ISO 8601. -.. function:: lastdayofweek(dt::TimeType) -> TimeType +.. function:: lastdayofweek(dt::TimeType[, lastday::DayOfWeek=Sunday]) -> TimeType .. Docstring generated from Julia source - Adjusts ``dt`` to the Sunday of its week. + Adjusts ``dt`` to the last day of its week. The optional second argument specifies the ``DayOfWeek`` which ends the week: by default, this is ``Sunday``\ , as per ISO 8601. .. function:: firstdayofmonth(dt::TimeType) -> TimeType @@ -497,25 +516,25 @@ Adjuster Functions Adjusts ``dt`` to the last day of its quarter. -.. function:: tonext(dt::TimeType,dow::Int;same::Bool=false) -> TimeType +.. function:: tonext(dt::TimeType, dow::DayOfWeek; same::Bool=false) -> TimeType .. Docstring generated from Julia source - Adjusts ``dt`` to the next day of week corresponding to ``dow`` with ``1 = Monday, 2 = Tuesday, etc``\ . Setting ``same=true`` allows the current ``dt`` to be considered as the next ``dow``\ , allowing for no adjustment to occur. + Adjusts ``dt`` to the next day of week corresponding to ``dow``\ . Setting ``same=true`` allows the current ``dt`` to be considered as the next ``dow``\ , allowing for no adjustment to occur. -.. function:: toprev(dt::TimeType,dow::Int;same::Bool=false) -> TimeType +.. function:: toprev(dt::TimeType, dow::DayOfWeek; same::Bool=false) -> TimeType .. Docstring generated from Julia source - Adjusts ``dt`` to the previous day of week corresponding to ``dow`` with ``1 = Monday, 2 = Tuesday, etc``\ . Setting ``same=true`` allows the current ``dt`` to be considered as the previous ``dow``\ , allowing for no adjustment to occur. + Adjusts ``dt`` to the previous day of week corresponding to ``dow``\ . Setting ``same=true`` allows the current ``dt`` to be considered as the previous ``dow``\ , allowing for no adjustment to occur. -.. function:: tofirst(dt::TimeType,dow::Int;of=Month) -> TimeType +.. function:: tofirst(dt::TimeType, dow::DayOfWeek; of=Month) -> TimeType .. Docstring generated from Julia source Adjusts ``dt`` to the first ``dow`` of its month. Alternatively, ``of=Year`` will adjust to the first ``dow`` of the year. -.. function:: tolast(dt::TimeType,dow::Int;of=Month) -> TimeType +.. function:: tolast(dt::TimeType, dow::DayOfWeek; of=Month) -> TimeType .. Docstring generated from Julia source diff --git a/test/dates/adjusters.jl b/test/dates/adjusters.jl index 1448b16dba3e4..8dc1bb300f1a8 100644 --- a/test/dates/adjusters.jl +++ b/test/dates/adjusters.jl @@ -95,6 +95,10 @@ g = Dates.Date(2014,1,12) @test Dates.firstdayofweek(e) == a @test Dates.firstdayofweek(f) == a @test Dates.firstdayofweek(g) == a +@test Dates.firstdayofweek(c, Dates.Mon) == a +@test Dates.firstdayofweek(c, Dates.Wed) == c +@test Dates.firstdayofweek(c, Dates.Sun) == Dates.Date(2014,1,5) + # Test firstdayofweek over the course of the year dt = a for i = 0:364 @@ -137,6 +141,11 @@ g = Dates.Date(2014,1,12) @test Dates.lastdayofweek(e) == g @test Dates.lastdayofweek(f) == g @test Dates.lastdayofweek(g) == g + +@test Dates.lastdayofweek(c, Dates.Sun) == g +@test Dates.lastdayofweek(c, Dates.Sat) == f +@test Dates.lastdayofweek(g, Dates.Sat) == Dates.Date(2014,1,18) + dt = a for i = 0:364 @test Dates.lastdayofweek(dt) == g + Dates.Week(div(i,7)) @@ -217,8 +226,6 @@ dt = Dates.Date(2014,5,21) @test Dates.tonext(dt,Dates.Sun) == Dates.Date(2014,5,25) @test Dates.tonext(dt,Dates.Mon) == Dates.Date(2014,5,26) @test Dates.tonext(dt,Dates.Tue) == Dates.Date(2014,5,27) -# No dayofweek function for out of range values -@test_throws KeyError Dates.tonext(dt,8) @test Dates.tonext(Dates.Date(0),Dates.Mon) == Dates.Date(0,1,3) @@ -262,8 +269,6 @@ dt = Dates.Date(2014,5,21) @test Dates.toprev(dt,Dates.Sun) == Dates.Date(2014,5,18) @test Dates.toprev(dt,Dates.Mon) == Dates.Date(2014,5,19) @test Dates.toprev(dt,Dates.Tue) == Dates.Date(2014,5,20) -# No dayofweek function for out of range values -@test_throws KeyError Dates.toprev(dt,8) @test Dates.toprev(Dates.Date(0),Dates.Mon) == Dates.Date(-1,12,27) @@ -337,7 +342,7 @@ Januarymondays2014 = [Dates.Date(2014,1,6),Dates.Date(2014,1,13),Dates.Date(2014 end) == 24 # Thanksgiving: 4th Thursday of November -thanksgiving = x->Dates.dayofweek(x) == Dates.Thu && +thanksgiving = x->Dates.DayOfWeek(x) == Dates.Thu && Dates.month(x) == Dates.Nov && Dates.dayofweekofmonth(x) == 4 @@ -354,7 +359,7 @@ end == Dates.Date(2013,11,28) # Pittsburgh street cleaning dr = Dates.Date(2014):Dates.Date(2015) @test length(filter(dr) do x - Dates.dayofweek(x) == Dates.Tue && + Dates.DayOfWeek(x) == Dates.Tue && Dates.April < Dates.month(x) < Dates.Nov && Dates.dayofweekofmonth(x) == 2 end) == 6 @@ -369,19 +374,19 @@ isnewyears(dt) = Dates.yearmonthday(dt) == newyears(Dates.year(dt)) isindependenceday(dt) = Dates.yearmonthday(dt) == independenceday(Dates.year(dt)) isveteransday(dt) = Dates.yearmonthday(dt) == veteransday(Dates.year(dt)) ischristmas(dt) = Dates.yearmonthday(dt) == christmas(Dates.year(dt)) -ismartinlutherking(dt) = Dates.dayofweek(dt) == Dates.Mon && +ismartinlutherking(dt) = Dates.DayOfWeek(dt) == Dates.Mon && Dates.month(dt) == Dates.Jan && Dates.dayofweekofmonth(dt) == 3 -ispresidentsday(dt) = Dates.dayofweek(dt) == Dates.Mon && +ispresidentsday(dt) = Dates.DayOfWeek(dt) == Dates.Mon && Dates.month(dt) == Dates.Feb && Dates.dayofweekofmonth(dt) == 3 # Last Monday of May -ismemorialday(dt) = Dates.dayofweek(dt) == Dates.Mon && +ismemorialday(dt) = Dates.DayOfWeek(dt) == Dates.Mon && Dates.month(dt) == Dates.May && Dates.dayofweekofmonth(dt) == Dates.daysofweekinmonth(dt) -islaborday(dt) = Dates.dayofweek(dt) == Dates.Mon && +islaborday(dt) = Dates.DayOfWeek(dt) == Dates.Mon && Dates.month(dt) == Dates.Sep && Dates.dayofweekofmonth(dt) == 1 -iscolumbusday(dt) = Dates.dayofweek(dt) == Dates.Mon && +iscolumbusday(dt) = Dates.DayOfWeek(dt) == Dates.Mon && Dates.month(dt) == Dates.Oct && Dates.dayofweekofmonth(dt) == 2 -isthanksgiving(dt) = Dates.dayofweek(dt) == Dates.Thu && +isthanksgiving(dt) = Dates.DayOfWeek(dt) == Dates.Thu && Dates.month(dt) == Dates.Nov && Dates.dayofweekofmonth(dt) == 4 function easter(y) @@ -414,13 +419,13 @@ const HOLIDAYS = x->isnewyears(x) || isindependenceday(x) || const OBSERVEDHOLIDAYS = x->begin # If the holiday is on a weekday - if HOLIDAYS(x) && Dates.dayofweek(x) < Dates.Saturday + if HOLIDAYS(x) && Dates.DayOfWeek(x) < Dates.Sat return true # Holiday is observed Monday if falls on Sunday - elseif Dates.dayofweek(x) == 1 && HOLIDAYS(x-Dates.Day(1)) + elseif Dates.DayOfWeek(x) == Dates.Mon && HOLIDAYS(x-Dates.Day(1)) return true # Holiday is observed Friday if falls on Saturday - elseif Dates.dayofweek(x) == 5 && HOLIDAYS(x+Dates.Day(1)) + elseif Dates.DayOfWeek(x) == Dates.Fri && HOLIDAYS(x+Dates.Day(1)) return true else return false @@ -437,7 +442,7 @@ observed = filter(OBSERVEDHOLIDAYS,Dates.Date(1999):Dates.Date(2000)) # we just look at weekend days and negate the result @test length(filter(Dates.Date(2014):Dates.Date(2015)) do x !(OBSERVEDHOLIDAYS(x) || - Dates.dayofweek(x) > 5) + Dates.DayOfWeek(x) > Dates.Fri) end) == 251 # First day of the next month for each day of 2014 @@ -450,7 +455,7 @@ end) == 251 @test length(filter(Date(2000):Dates.Month(1):Date(2016)) do dt sum = 0 for i = 1:7 - sum += Dates.dayofweek(dt) > 4 ? Dates.daysofweekinmonth(dt) : 0 + sum += Dates.DayOfWeek(dt) > Dates.Thu ? Dates.daysofweekinmonth(dt) : 0 dt += Dates.Day(1) end return sum == 15 diff --git a/test/dates/query.jl b/test/dates/query.jl index 5ffe81d6b0e90..96e8bd3d28c6c 100644 --- a/test/dates/query.jl +++ b/test/dates/query.jl @@ -27,11 +27,11 @@ for (i,dt) in enumerate([Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec]) @test Dates.monthname(i) == monthnames[i] @test Dates.monthabbr(dt) == monthnames[i][1:3] @test Dates.monthabbr(i) == monthnames[i][1:3] - @test Dates.dayofweek(dt) == daysofweek[i] + @test Dates.DayOfWeek(dt) == daysofweek[i] @test Dates.dayname(dt) == dows[i] - @test Dates.dayname(Dates.dayofweek(dt)) == dows[i] + @test Dates.dayname(Dates.DayOfWeek(dt)) == dows[i] @test Dates.dayabbr(dt) == dows[i][1:3] - @test Dates.dayabbr(Dates.dayofweek(dt)) == dows[i][1:3] + @test Dates.dayabbr(Dates.DayOfWeek(dt)) == dows[i][1:3] @test Dates.daysinmonth(dt) == daysinmonth[i] end @@ -84,14 +84,14 @@ Dates.VALUETOMONTH["french"] = french_months @test Dates.daysinyear(Dates.DateTime(2001)) == 365 # Days of week from Monday = 1 to Sunday = 7 -@test Dates.dayofweek(Dates.DateTime(2013,12,22)) == 7 -@test Dates.dayofweek(Dates.DateTime(2013,12,23)) == 1 -@test Dates.dayofweek(Dates.DateTime(2013,12,24)) == 2 -@test Dates.dayofweek(Dates.DateTime(2013,12,25)) == 3 -@test Dates.dayofweek(Dates.DateTime(2013,12,26)) == 4 -@test Dates.dayofweek(Dates.DateTime(2013,12,27)) == 5 -@test Dates.dayofweek(Dates.DateTime(2013,12,28)) == 6 -@test Dates.dayofweek(Dates.DateTime(2013,12,29)) == 7 +@test Dates.DayOfWeek(Dates.DateTime(2013,12,22)) == Dates.Sun +@test Dates.DayOfWeek(Dates.DateTime(2013,12,23)) == Dates.Mon +@test Dates.DayOfWeek(Dates.DateTime(2013,12,24)) == Dates.Tue +@test Dates.DayOfWeek(Dates.DateTime(2013,12,25)) == Dates.Wed +@test Dates.DayOfWeek(Dates.DateTime(2013,12,26)) == Dates.Thu +@test Dates.DayOfWeek(Dates.DateTime(2013,12,27)) == Dates.Fri +@test Dates.DayOfWeek(Dates.DateTime(2013,12,28)) == Dates.Sat +@test Dates.DayOfWeek(Dates.DateTime(2013,12,29)) == Dates.Sun # There are 5 Sundays in December, 2013 @test Dates.daysofweekinmonth(Dates.DateTime(2013,12,1)) == 5 From 79a19f8f724f6db72c59cf65957f740acd5f0ea2 Mon Sep 17 00:00:00 2001 From: Simon Byrne Date: Fri, 4 Nov 2016 13:51:59 +0000 Subject: [PATCH 2/2] deprecate Dates.ismonday, etc --- base/dates/query.jl | 9 ------ base/deprecated.jl | 8 +++++ test/dates/adjusters.jl | 66 ++++++++++++++++++++--------------------- 3 files changed, 41 insertions(+), 42 deletions(-) diff --git a/base/dates/query.jl b/base/dates/query.jl index f374f4d8a1465..1a0cde0827fd4 100644 --- a/base/dates/query.jl +++ b/base/dates/query.jl @@ -67,15 +67,6 @@ in the given `locale`. """ dayabbr(dt::TimeType;locale::AbstractString="english") = VALUETODAYOFWEEKABBR[locale][DayOfWeek(dt)] -# Convenience methods for each day -ismonday(dt::TimeType) = DayOfWeek(dt) == Mon -istuesday(dt::TimeType) = DayOfWeek(dt) == Tue -iswednesday(dt::TimeType) = DayOfWeek(dt) == Wed -isthursday(dt::TimeType) = DayOfWeek(dt) == Thu -isfriday(dt::TimeType) = DayOfWeek(dt) == Fri -issaturday(dt::TimeType) = DayOfWeek(dt) == Sat -issunday(dt::TimeType) = DayOfWeek(dt) == Sun - # i.e. 1st Monday? 2nd Monday? 3rd Wednesday? 5th Sunday? """ dayofweekofmonth(dt::TimeType) -> Int diff --git a/base/deprecated.jl b/base/deprecated.jl index dac180b1dcf81..d5558a827ce21 100644 --- a/base/deprecated.jl +++ b/base/deprecated.jl @@ -1127,6 +1127,7 @@ eval(Base.Dates, quote end end recur{T<:TimeType}(fun::Function, start::T, stop::T; step::Period=Day(1), negate::Bool=false, limit::Int=10000) = recur(fun, start:step:stop; negate=negate) +end) # #19212 eval(Base.Dates,quote @@ -1143,6 +1144,13 @@ eval(Base.Dates,quote dayname(DayOfWeek(dt); locale=locale)) @deprecate(dayabbr(dt::Integer;locale::AbstractString="english"), dayabbr(DayOfWeek(dt); locale=locale)) + @deprecate(ismonday(dt::TimeType), DayOfWeek(dt) == Mon) + @deprecate(istuesday(dt::TimeType), DayOfWeek(dt) == Tue) + @deprecate(iswednesday(dt::TimeType), DayOfWeek(dt) == Wed) + @deprecate(isthursday(dt::TimeType), DayOfWeek(dt) == Thu) + @deprecate(isfriday(dt::TimeType), DayOfWeek(dt) == Fri) + @deprecate(issaturday(dt::TimeType), DayOfWeek(dt) == Sat) + @deprecate(issunday(dt::TimeType), DayOfWeek(dt) == Sun) end) # End deprecations scheduled for 0.6 diff --git a/test/dates/adjusters.jl b/test/dates/adjusters.jl index 8dc1bb300f1a8..02b80dbe70cee 100644 --- a/test/dates/adjusters.jl +++ b/test/dates/adjusters.jl @@ -206,11 +206,11 @@ end # Adjusters # Adjuster Constructors -@test Dates.Date(Dates.ismonday,2014) == Dates.Date(2014,1,6) -@test Dates.Date(Dates.ismonday,2014,5) == Dates.Date(2014,5,5) +@test Dates.Date(x->Dates.DayOfWeek(x)==Dates.Mon,2014) == Dates.Date(2014,1,6) +@test Dates.Date(x->Dates.DayOfWeek(x)==Dates.Mon,2014,5) == Dates.Date(2014,5,5) -@test Dates.DateTime(Dates.ismonday,2014) == Dates.DateTime(2014,1,6) -@test Dates.DateTime(Dates.ismonday,2014,5) == Dates.DateTime(2014,5,5) +@test Dates.DateTime(x->Dates.DayOfWeek(x)==Dates.Mon,2014) == Dates.DateTime(2014,1,6) +@test Dates.DateTime(x->Dates.DayOfWeek(x)==Dates.Mon,2014,5) == Dates.DateTime(2014,5,5) @test Dates.DateTime(x->Dates.hour(x)==12,2014,5,21) == Dates.DateTime(2014,5,21,12) @test Dates.DateTime(x->Dates.minute(x)==30,2014,5,21,12) == Dates.DateTime(2014,5,21,12,30) @test Dates.DateTime(x->Dates.second(x)==30,2014,5,21,12,30) == Dates.DateTime(2014,5,21,12,30,30) @@ -230,35 +230,35 @@ dt = Dates.Date(2014,5,21) @test Dates.tonext(Dates.Date(0),Dates.Mon) == Dates.Date(0,1,3) #test func, diff steps, negate, same -@test Dates.tonext(Dates.iswednesday,dt) == Dates.Date(2014,5,28) -@test Dates.tonext(Dates.iswednesday,dt;same=true) == dt -@test Dates.tonext(Dates.isthursday,dt) == Dates.Date(2014,5,22) -@test Dates.tonext(Dates.isfriday,dt) == Dates.Date(2014,5,23) -@test Dates.tonext(Dates.issaturday,dt) == Dates.Date(2014,5,24) -@test Dates.tonext(Dates.issunday,dt) == Dates.Date(2014,5,25) -@test Dates.tonext(Dates.ismonday,dt) == Dates.Date(2014,5,26) -@test Dates.tonext(Dates.istuesday,dt) == Dates.Date(2014,5,27) -@test Dates.tonext(Dates.ismonday,Dates.Date(0)) == Dates.Date(0,1,3) - -@test Dates.tonext(x->!Dates.iswednesday(x),dt;negate=true) == Dates.Date(2014,5,28) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt) == Dates.Date(2014,5,28) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;same=true) == dt +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Thu,dt) == Dates.Date(2014,5,22) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Fri,dt) == Dates.Date(2014,5,23) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Sat,dt) == Dates.Date(2014,5,24) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Sun,dt) == Dates.Date(2014,5,25) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Mon,dt) == Dates.Date(2014,5,26) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Tue,dt) == Dates.Date(2014,5,27) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Mon,Dates.Date(0)) == Dates.Date(0,1,3) + +@test Dates.tonext(x->Dates.DayOfWeek(x)!=Dates.Wed,dt;negate=true) == Dates.Date(2014,5,28) # Reach adjust limit -@test_throws ArgumentError Dates.tonext(Dates.iswednesday,dt;limit=6) - -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Day(2)) == Dates.Date(2014,6,4) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Day(3)) == Dates.Date(2014,6,11) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Day(4)) == Dates.Date(2014,6,18) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Day(5)) == Dates.Date(2014,6,25) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Day(6)) == Dates.Date(2014,7,2) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Day(7)) == Dates.Date(2014,5,28) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Week(1)) == Dates.Date(2014,5,28) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Week(2)) == Dates.Date(2014,6,4) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Week(3)) == Dates.Date(2014,6,11) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Week(4)) == Dates.Date(2014,6,18) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Week(5)) == Dates.Date(2014,6,25) -@test Dates.tonext(Dates.iswednesday,dt;step=Dates.Week(6)) == Dates.Date(2014,7,2) - -@test Dates.tonext(Dates.iswednesday,dt;same=true) == dt -@test Dates.tonext(Dates.isthursday,dt) == Dates.Date(2014,5,22) +@test_throws ArgumentError Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;limit=6) + +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Day(2)) == Dates.Date(2014,6,4) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Day(3)) == Dates.Date(2014,6,11) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Day(4)) == Dates.Date(2014,6,18) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Day(5)) == Dates.Date(2014,6,25) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Day(6)) == Dates.Date(2014,7,2) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Day(7)) == Dates.Date(2014,5,28) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Week(1)) == Dates.Date(2014,5,28) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Week(2)) == Dates.Date(2014,6,4) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Week(3)) == Dates.Date(2014,6,11) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Week(4)) == Dates.Date(2014,6,18) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Week(5)) == Dates.Date(2014,6,25) +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;step=Dates.Week(6)) == Dates.Date(2014,7,2) + +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Wed,dt;same=true) == dt +@test Dates.tonext(x->Dates.DayOfWeek(x)==Dates.Thu,dt) == Dates.Date(2014,5,22) #toprev @test Dates.toprev(dt,Dates.Wed) == Dates.Date(2014,5,14) @@ -317,7 +317,7 @@ stopdate = Dates.Date(2014,2,1) @test length(filter(x->true,stopdate:Dates.Day(-1):startdate)) == 32 Januarymondays2014 = [Dates.Date(2014,1,6),Dates.Date(2014,1,13),Dates.Date(2014,1,20),Dates.Date(2014,1,27)] -@test filter(Dates.ismonday,startdate:stopdate) == Januarymondays2014 +@test filter(x->Dates.DayOfWeek(x)==Dates.Mon,startdate:stopdate) == Januarymondays2014 @test_throws MethodError filter((x,y)->x+y,Dates.Date(2013):Dates.Date(2014)) @test_throws MethodError Dates.DateFunction((x,y)->x+y, false, Date(0))