Skip to content

Commit

Permalink
Deprecate parse(::AbstractString, ::DateFormat)
Browse files Browse the repository at this point in the history
Properly deprecates the `Dates.parse(::AbstractString, ::DateFormat)`
function which returned an `Array{Period}`. Replaces this function with
`parse(::Type{Array{Period}}, ::AbstractString, ::DateFormat)`. Slightly
differs from the original function by returning the periods in the
order of the `DateFormat` and not in reverse sorted order.
  • Loading branch information
omus committed Mar 3, 2017
1 parent 017f5b4 commit 67189c9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
55 changes: 55 additions & 0 deletions base/dates/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,3 +200,58 @@ function Base.parse(::Type{DateTime}, s::AbstractString, df::typeof(ISODateTimeF
@label error
throw(ArgumentError("Invalid DateTime string"))
end

@generated function tryparse_internal{S, F}(::Type{Array{Period}}, str::AbstractString, df::DateFormat{S, F}, raise::Bool=false)
token_types = Type[dp <: DatePart ? SLOT_RULE[first(dp.parameters)] : Void for dp in F.parameters]
N = length(token_types)

field_order = sizehint!(Int[], N)
field_types = sizehint!(Type[], N)
for (i, typ) in enumerate(token_types)
if typ <: Period
push!(field_order, i)
push!(field_types, typ)
end
end
field_parsers = collect(zip(field_order, field_types))

quote
periods = sizehint!(Period[], $(length(field_parsers)))
t = df.tokens
l = df.locale
pos, len = start(str), endof(str)

err_idx = 1
Base.@nexprs $N i->val_i = 0
Base.@nexprs $N i->(begin
pos > len && @goto done
nv, next_pos = tryparsenext(t[i], str, pos, len, l)
isnull(nv) && @goto error
val_i, pos = unsafe_get(nv), next_pos
err_idx += 1
end)
pos <= len && @goto error

@label done
parts = Base.@ntuple $N val
for (i, P) in $field_parsers
if i < err_idx
push!(periods, P(parts[i]))
end
end
return periods

@label error
# Note: Keeping exception generation in separate function helps with performance
raise && throw(gen_exception(t, err_idx, pos))
return periods
end
end

function Base.tryparse{T<:Array{Period}}(::Type{T}, str::AbstractString, df::DateFormat)
tryparse_internal(T, str, df, false)
end

function Base.parse{T<:Array{Period}}(::Type{T}, str::AbstractString, df::DateFormat)
tryparse_internal(T, str, df, true)
end
8 changes: 8 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,14 @@ end
@deprecate_binding LinearSlow IndexCartesian false
@deprecate_binding linearindexing IndexStyle false

# #20876
@eval Base.Dates begin
function Base.Dates.parse(x::AbstractString, df::DateFormat)
Base.depwarn("`Dates.parse(x::AbstractString, df::DateFormat)` is deprecated, use `sort!(parse(Array{Dates.Period}, x, df), rev=true, lt=Dates.periodisless)` instead.", :parse)
sort!(parse(Array{Period}, x, df), rev=true, lt=periodisless)
end
end

# END 0.6 deprecations

# BEGIN 1.0 deprecations
Expand Down
14 changes: 11 additions & 3 deletions test/dates/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,18 @@
# DateTime parsing
# Useful reference for different locales: http://library.princeton.edu/departments/tsd/katmandu/reference/months.html

let str = "1996/02/15 24:00", format = "yyyy/mm/dd HH:MM"
expected = (1996, 2, 15, 24, 0, 0, 0)
@test get(Dates.tryparse_internal(DateTime, str, Dates.DateFormat(format))) == expected
# Using parse(::Array{Period}, ...) allows for more flexibility.
let str = "02/15/1996 24:00", format = Dates.DateFormat("mm/dd/yyyy HH:MM"), T = Array{Dates.Period}
@test_throws ArgumentError Dates.DateTime(str, Dates.DateFormat(format))

expected = [Dates.Month(2), Dates.Day(15), Dates.Year(1996), Dates.Hour(24), Dates.Minute(0)]
@test Dates.parse(T, str, Dates.DateFormat(format)) == expected
end

let T = Array{Dates.Period}
expected = Dates.Period[Dates.Year(2017), Dates.Month(3)]
@test Dates.parse(T, "2017-03", DateFormat("yyyy-mm-dd")) == expected
@test_throws ArgumentError Dates.parse(T, "2017-03-03", DateFormat("yyyy-mm"))
end

# DateFormat printing
Expand Down

0 comments on commit 67189c9

Please sign in to comment.