Skip to content

Commit 9a96fc2

Browse files
authored
Merge b0f6c75 into a132ae2
2 parents a132ae2 + b0f6c75 commit 9a96fc2

File tree

4 files changed

+267
-113
lines changed

4 files changed

+267
-113
lines changed

base/dates/io.jl

+34-17
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,17 @@ Delim(d::Char) = Delim{Char, 1}(d)
175175
Delim(d::String) = Delim{String, length(d)}(d)
176176

177177
@inline function tryparsenext{N}(d::Delim{Char, N}, str, i::Int, len)
178-
R = Nullable{Int64}
178+
R = Nullable{Bool}
179179
for j=1:N
180180
i > len && return (R(), i)
181181
c, i = next(str, i)
182182
c != d.d && return (R(), i)
183183
end
184-
return R(0), i
184+
return R(true), i
185185
end
186186

187187
@inline function tryparsenext{N}(d::Delim{String, N}, str, i::Int, len)
188-
R = Nullable{Int64}
188+
R = Nullable{Bool}
189189
i1 = i
190190
i2 = start(d.d)
191191
for j = 1:N
@@ -198,15 +198,15 @@ end
198198
return R(), i1
199199
end
200200
end
201-
return R(0), i1
201+
return R(true), i1
202202
end
203203

204204
@inline function format(io, d::Delim, dt, locale)
205205
write(io, d.d)
206206
end
207207

208208
function _show_content{N}(io::IO, d::Delim{Char, N})
209-
if d.d in keys(SLOT_RULE)
209+
if d.d in keys(CONVERSION_SPECIFIERS)
210210
for i = 1:N
211211
write(io, '\\', d.d)
212212
end
@@ -219,7 +219,7 @@ end
219219

220220
function _show_content(io::IO, d::Delim)
221221
for c in d.d
222-
if c in keys(SLOT_RULE)
222+
if c in keys(CONVERSION_SPECIFIERS)
223223
write(io, '\\')
224224
end
225225
write(io, c)
@@ -236,8 +236,9 @@ end
236236

237237
abstract type DayOfWeekToken end # special addition to Period types
238238

239-
# mapping format specifiers to period types
240-
const SLOT_RULE = Dict{Char, Type}(
239+
# Map conversion specifiers or character codes to tokens.
240+
# Note: Allow addition of new character codes added by packages
241+
const CONVERSION_SPECIFIERS = Dict{Char, Type}(
241242
'y' => Year,
242243
'Y' => Year,
243244
'm' => Month,
@@ -252,13 +253,26 @@ const SLOT_RULE = Dict{Char, Type}(
252253
's' => Millisecond,
253254
)
254255

255-
slot_order(::Type{Date}) = (Year, Month, Day)
256-
slot_order(::Type{DateTime}) = (Year, Month, Day, Hour, Minute, Second, Millisecond)
257-
258-
slot_defaults(::Type{Date}) = map(Int64, (1, 1, 1))
259-
slot_defaults(::Type{DateTime}) = map(Int64, (1, 1, 1, 0, 0, 0, 0))
256+
# Default values are needed when a conversion specifier is used in a DateFormat for parsing
257+
# and we have reached the end of the input string.
258+
# Note: Allow `Any` value as a default to support extensibility
259+
const CONVERSION_DEFAULTS = Dict{Type, Any}(
260+
Year => Int64(1),
261+
Month => Int64(1),
262+
DayOfWeekToken => Int64(0),
263+
Day => Int64(1),
264+
Hour => Int64(0),
265+
Minute => Int64(0),
266+
Second => Int64(0),
267+
Millisecond => Int64(0),
268+
)
260269

261-
slot_types{T<:TimeType}(::Type{T}) = typeof(slot_defaults(T))
270+
# Specifies the required fields in order to parse a TimeType
271+
# Note: Allows for addition of new TimeTypes
272+
const CONVERSION_TRANSLATIONS = Dict{Type{<:TimeType}, Tuple}(
273+
Date => (Year, Month, Day),
274+
DateTime => (Year, Month, Day, Hour, Minute, Second, Millisecond),
275+
)
262276

263277
"""
264278
DateFormat(format::AbstractString, locale="english") -> DateFormat
@@ -300,13 +314,13 @@ function DateFormat(f::AbstractString, locale::DateLocale=ENGLISH)
300314
prev = ()
301315
prev_offset = 1
302316

303-
letters = String(collect(keys(Base.Dates.SLOT_RULE)))
317+
letters = String(collect(keys(CONVERSION_SPECIFIERS)))
304318
for m in eachmatch(Regex("(?<!\\\\)([\\Q$letters\\E])\\1*"), f)
305319
tran = replace(f[prev_offset:m.offset - 1], r"\\(.)", s"\1")
306320

307321
if !isempty(prev)
308322
letter, width = prev
309-
typ = SLOT_RULE[letter]
323+
typ = CONVERSION_SPECIFIERS[letter]
310324

311325
push!(tokens, DatePart{letter}(width, isempty(tran)))
312326
end
@@ -326,7 +340,7 @@ function DateFormat(f::AbstractString, locale::DateLocale=ENGLISH)
326340

327341
if !isempty(prev)
328342
letter, width = prev
329-
typ = SLOT_RULE[letter]
343+
typ = CONVERSION_SPECIFIERS[letter]
330344

331345
push!(tokens, DatePart{letter}(width, false))
332346
end
@@ -368,6 +382,9 @@ const ISODateTimeFormat = DateFormat("yyyy-mm-dd\\THH:MM:SS.s")
368382
const ISODateFormat = DateFormat("yyyy-mm-dd")
369383
const RFC1123Format = DateFormat("e, dd u yyyy HH:MM:SS")
370384

385+
default_format(::Type{DateTime}) = ISODateTimeFormat
386+
default_format(::Type{Date}) = ISODateFormat
387+
371388
### API
372389
"""
373390
DateTime(dt::AbstractString, format::AbstractString; locale="english") -> DateTime

0 commit comments

Comments
 (0)