Skip to content

Commit 01ef3c3

Browse files
authored
deprecate Dates.recur in favour of filter (#19288)
* deprecate Dates.recur in favour of filter
1 parent 5310bd6 commit 01ef3c3

File tree

6 files changed

+72
-60
lines changed

6 files changed

+72
-60
lines changed

NEWS.md

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ Deprecated or removed
7474

7575
* infix operator `$` has been deprecated in favor of infix `` or function `xor()` ([#18977]).
7676

77+
* `Dates.recur` has been deprecated in favor of `filter` ([#19288])
78+
7779
Julia v0.5.0 Release Notes
7880
==========================
7981

@@ -702,3 +704,4 @@ Language tooling improvements
702704
[#18839]: https://github.com/JuliaLang/julia/issues/18839
703705
[#19018]: https://github.com/JuliaLang/julia/issues/19018
704706
[#19233]: https://github.com/JuliaLang/julia/issues/19233
707+
[#19288]: https://github.com/JuliaLang/julia/issues/19288

base/dates/Dates.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export Period, DatePeriod, TimePeriod,
4040
firstdayofmonth, lastdayofmonth,
4141
firstdayofyear, lastdayofyear,
4242
firstdayofquarter, lastdayofquarter,
43-
adjust, tonext, toprev, tofirst, tolast, recur,
43+
adjust, tonext, toprev, tofirst, tolast,
4444
# io.jl
4545
ISODateTimeFormat, ISODateFormat, DateFormat, RFC1123Format
4646

base/dates/adjusters.jl

-26
Original file line numberDiff line numberDiff line change
@@ -260,29 +260,3 @@ function tolast(dt::TimeType, dow::Int; of::Union{Type{Year}, Type{Month}}=Month
260260
dt = of <: Month ? lastdayofmonth(dt) : lastdayofyear(dt)
261261
return adjust(ISDAYOFWEEK[dow], dt, Day(-1), 366)
262262
end
263-
264-
function recur{T<:TimeType}(fun::Function, start::T, stop::T; step::Period=Day(1), negate::Bool=false, limit::Int=10000)
265-
((start != stop) & ((step > zero(step)) != (stop > start))) && return T[]
266-
a = T[]
267-
check = start <= stop ? 1 : -1
268-
df = Dates.DateFunction(fun, negate, start)
269-
while true
270-
next = Dates.adjust(df, start, step, limit)
271-
cmp(next, stop) == check && break
272-
push!(a, next)
273-
start = next + step
274-
end
275-
return a
276-
end
277-
278-
"""
279-
recur{T<:TimeType}(func::Function,dr::StepRange{T};negate=false,limit=10000) -> Vector{T}
280-
281-
`func` takes a single TimeType argument and returns a `Bool` indicating whether the input
282-
should be "included" in the final set. `recur` applies `func` over each element in the range
283-
of `dr`, including those elements for which `func` returns `true` in the resulting Array,
284-
unless `negate=true`, then only elements where `func` returns `false` are included.
285-
"""
286-
function recur{T<:TimeType}(fun::Function, dr::StepRange{T};negate::Bool=false, limit::Int=10000)
287-
return recur(fun, first(dr), last(dr); step=step(dr), negate=negate, limit=limit)
288-
end

base/deprecated.jl

+13
Original file line numberDiff line numberDiff line change
@@ -1116,4 +1116,17 @@ Filesystem.stop_watching(stream::Filesystem._FDWatcher) = depwarn("stop_watching
11161116
@deprecate takebuf_array take!
11171117
@deprecate takebuf_string(b) String(take!(b))
11181118

1119+
# #19288
1120+
eval(Base.Dates, quote
1121+
function recur{T<:TimeType}(fun::Function, dr::StepRange{T}; negate::Bool=false, limit::Int=10000)
1122+
depwarn("Dates.recur is deprecated, use filter instead.",:recur)
1123+
if negate
1124+
filter(x -> !f(x), dr)
1125+
else
1126+
filter(f, dr)
1127+
end
1128+
end
1129+
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)
1130+
end)
1131+
11191132
# End deprecations scheduled for 0.6

doc/manual/dates.rst

+29-4
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,33 @@ What's going on there? In the first line, we're adding 1 day to January 29th, wh
260260

261261
Tricky? Perhaps. What is an innocent :mod:`Dates` user to do? The bottom line is to be aware that explicitly forcing a certain associativity, when dealing with months, may lead to some unexpected results, but otherwise, everything should work as expected. Thankfully, that's pretty much the extent of the odd cases in date-period arithmetic when dealing with time in UT (avoiding the "joys" of dealing with daylight savings, leap seconds, etc.).
262262

263+
As a bonus, all period arithmetic objects work directly with ranges::
264+
265+
julia> dr = Date(2014,1,29):Date(2014,2,3)
266+
2014-01-29:1 day:2014-02-03
267+
268+
julia> collect(dr)
269+
6-element Array{Date,1}:
270+
2014-01-29
271+
2014-01-30
272+
2014-01-31
273+
2014-02-01
274+
2014-02-02
275+
2014-02-03
276+
277+
julia> dr = Date(2014,1,29):Dates.Month(1):Date(2014,07,29)
278+
2014-01-29:1 month:2014-07-29
279+
280+
julia> collect(dr)
281+
7-element Array{Date,1}:
282+
2014-01-29
283+
2014-02-28
284+
2014-03-29
285+
2014-04-29
286+
2014-05-29
287+
2014-06-29
288+
2014-07-29
289+
263290

264291
Adjuster Functions
265292
------------------
@@ -305,14 +332,12 @@ This is useful with the do-block syntax for more complex temporal expressions::
305332
end
306333
2014-11-27
307334

308-
The final method in the adjuster API is the :func:`recur` function. :func:`recur` vectorizes the adjustment process by taking a start and stop date (optionally specificed by a :class:`StepRange`), along with a :class:`DateFunction` to specify all valid dates/moments to be returned in the specified range. In this case, the :class:`DateFunction` is often referred to as the "inclusion" function because it specifies (by returning ``true``) which dates/moments should be included in the returned vector of dates.
309-
310-
::
335+
The :func:`Base.filter` method can be used to obtain all valid dates/moments in a specified range::
311336

312337
# Pittsburgh street cleaning; Every 2nd Tuesday from April to November
313338
# Date range from January 1st, 2014 to January 1st, 2015
314339
julia> dr = Dates.Date(2014):Dates.Date(2015);
315-
julia> recur(dr) do x
340+
julia> filter(dr) do x
316341
Dates.dayofweek(x) == Dates.Tue &&
317342
Dates.April <= Dates.month(x) <= Dates.Nov &&
318343
Dates.dayofweekofmonth(x) == 2

test/dates/adjusters.jl

+26-29
Original file line numberDiff line numberDiff line change
@@ -305,36 +305,34 @@ dt = Dates.Date(2014,5,21)
305305

306306
@test Dates.tolast(Dates.Date(0),Dates.Mon) == Dates.Date(0,1,31)
307307

308-
# recur
308+
# filter (was recur)
309309
startdate = Dates.Date(2014,1,1)
310310
stopdate = Dates.Date(2014,2,1)
311-
@test length(Dates.recur(x->true,startdate:stopdate)) == 32
312-
@test length(Dates.recur(x->true,stopdate:Dates.Day(-1):startdate)) == 32
311+
@test length(filter(x->true,startdate:stopdate)) == 32
312+
@test length(filter(x->true,stopdate:Dates.Day(-1):startdate)) == 32
313313

314314
Januarymondays2014 = [Dates.Date(2014,1,6),Dates.Date(2014,1,13),Dates.Date(2014,1,20),Dates.Date(2014,1,27)]
315-
@test Dates.recur(Dates.ismonday,startdate,stopdate) == Januarymondays2014
316-
@test Dates.recur(Dates.ismonday,startdate:stopdate) == Januarymondays2014
317-
@test Dates.recur(x->!Dates.ismonday(x),startdate,stopdate;negate=true) == Januarymondays2014
315+
@test filter(Dates.ismonday,startdate:stopdate) == Januarymondays2014
318316

319-
@test_throws MethodError Dates.recur((x,y)->x+y,Dates.Date(2013):Dates.Date(2014))
317+
@test_throws MethodError filter((x,y)->x+y,Dates.Date(2013):Dates.Date(2014))
320318
@test_throws MethodError Dates.DateFunction((x,y)->x+y, false, Date(0))
321319
@test_throws ArgumentError Dates.DateFunction((dt)->2, false, Date(0))
322-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,2))) == 32
323-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,1))) == 1
324-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,2))) == 2
325-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,3))) == 3
326-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,4))) == 4
327-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,5))) == 5
328-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,6))) == 6
329-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,7))) == 7
330-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2013,1,8))) == 8
331-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Month(1):Dates.Date(2013,1,1))) == 1
332-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Day(-1):Dates.Date(2012,1,1))) == 367
320+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,2))) == 32
321+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,1))) == 1
322+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,2))) == 2
323+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,3))) == 3
324+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,4))) == 4
325+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,5))) == 5
326+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,6))) == 6
327+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,7))) == 7
328+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2013,1,8))) == 8
329+
@test length(filter(x->true,Dates.Date(2013):Dates.Month(1):Dates.Date(2013,1,1))) == 1
330+
@test length(filter(x->true,Dates.Date(2013):Dates.Day(-1):Dates.Date(2012,1,1))) == 367
333331
# Empty range
334-
@test length(Dates.recur(x->true,Dates.Date(2013):Dates.Date(2012,1,1))) == 0
332+
@test length(filter(x->true,Dates.Date(2013):Dates.Date(2012,1,1))) == 0
335333

336334
# All leap days in 20th century
337-
@test length(Dates.recur(Dates.Date(1900):Dates.Date(2000)) do x
335+
@test length(filter(Dates.Date(1900):Dates.Date(2000)) do x
338336
Dates.month(x) == Dates.Feb && Dates.day(x) == 29
339337
end) == 24
340338

@@ -355,7 +353,7 @@ end == Dates.Date(2013,11,28)
355353

356354
# Pittsburgh street cleaning
357355
dr = Dates.Date(2014):Dates.Date(2015)
358-
@test length(Dates.recur(dr) do x
356+
@test length(filter(dr) do x
359357
Dates.dayofweek(x) == Dates.Tue &&
360358
Dates.April < Dates.month(x) < Dates.Nov &&
361359
Dates.dayofweekofmonth(x) == 2
@@ -412,7 +410,7 @@ const HOLIDAYS = x->isnewyears(x) || isindependenceday(x) ||
412410
ismemorialday(x) || islaborday(x) ||
413411
iscolumbusday(x) || isthanksgiving(x)
414412

415-
@test length(Dates.recur(HOLIDAYS,dr)) == 11
413+
@test length(filter(HOLIDAYS,dr)) == 11
416414

417415
const OBSERVEDHOLIDAYS = x->begin
418416
# If the holiday is on a weekday
@@ -429,18 +427,17 @@ const OBSERVEDHOLIDAYS = x->begin
429427
end
430428
end
431429

432-
observed = Dates.recur(OBSERVEDHOLIDAYS,Dates.Date(1999):Dates.Date(2000))
430+
observed = filter(OBSERVEDHOLIDAYS,Dates.Date(1999):Dates.Date(2000))
433431
@test length(observed) == 11
434432
@test observed[10] == Dates.Date(1999,12,24)
435433
@test observed[11] == Dates.Date(1999,12,31)
436434

437435
# Get all business/working days of 2014
438436
# Since we have already defined observed holidays,
439-
# we just look at weekend days and use the "negate" keyword of recur
440-
# validate with http://www.workingdays.us/workingdays_holidays_2014.htm
441-
@test length(Dates.recur(Dates.Date(2014):Dates.Date(2015);negate=true) do x
442-
OBSERVEDHOLIDAYS(x) ||
443-
Dates.dayofweek(x) > 5
437+
# we just look at weekend days and negate the result
438+
@test length(filter(Dates.Date(2014):Dates.Date(2015)) do x
439+
!(OBSERVEDHOLIDAYS(x) ||
440+
Dates.dayofweek(x) > 5)
444441
end) == 251
445442

446443
# First day of the next month for each day of 2014
@@ -450,7 +447,7 @@ end) == 251
450447
# From those goofy email forwards claiming a "special, lucky month"
451448
# that has 5 Fridays, 5 Saturdays, and 5 Sundays and that it only
452449
# occurs every 823 years
453-
@test length(Dates.recur(Date(2000):Dates.Month(1):Date(2016)) do dt
450+
@test length(filter(Date(2000):Dates.Month(1):Date(2016)) do dt
454451
sum = 0
455452
for i = 1:7
456453
sum += Dates.dayofweek(dt) > 4 ? Dates.daysofweekinmonth(dt) : 0

0 commit comments

Comments
 (0)