@@ -56,24 +56,28 @@ immutable DateFormat
56
56
trans # trans[i] == how to transition FROM slots[i] TO slots[i+1]
57
57
end
58
58
59
+ immutable DayOfWeekSlot <: AbstractTime end
60
+
59
61
duplicates (slots) = any (map (x-> count (y-> x. period== y. period,slots),slots) .> 1 )
60
62
61
63
function DateFormat (f:: String ,locale:: String = " english" )
62
64
slots = Slot[]
63
65
trans = {}
64
- begtran = match (r" ^.*?(?=[ymuUdHMSs ])" ,f). match
65
- ss = split (f,r" ^.*?(?=[ymuUdHMSs ])" )
66
- s = split (begtran == " " ? ss[1 ] : ss[2 ],r" [^ymuUdHMSs] |(?<=([ymuUdHMSs ])(?!\1 ))" )
66
+ begtran = match (r" ^.*?(?=[ymuUdHMSsEe ])" ,f). match
67
+ ss = split (f,r" ^.*?(?=[ymuUdHMSsEe ])" )
68
+ s = split (begtran == " " ? ss[1 ] : ss[2 ],r" [^ymuUdHMSsEe]+ |(?<=([ymuUdHMSsEe ])(?!\1 ))" )
67
69
for (i,k) in enumerate (s)
68
70
k == " " && break
69
71
tran = i >= endof (s) ? r" $" : match (Regex (" (?<=$(s[i]) ).*(?=$(s[i+ 1 ]) )" ),f). match
70
72
slot = tran == " " || tran == r" $" ? FixedWidthSlot : DelimitedSlot
71
73
width = length (k)
72
- typ = ' y' in k ? Year : ' m' in k ? Month :
74
+ typ = ' E' in k ? DayOfWeekSlot : ' e' in k ? DayOfWeekSlot :
75
+ ' y' in k ? Year : ' m' in k ? Month :
73
76
' u' in k ? Month : ' U' in k ? Month :
74
77
' d' in k ? Day : ' H' in k ? Hour :
75
78
' M' in k ? Minute : ' S' in k ? Second : Millisecond
76
- option = ' U' in k ? 2 : ' u' in k ? 1 : 0
79
+ option = ' E' in k ? 2 : ' e' in k ? 1 :
80
+ ' U' in k ? 2 : ' u' in k ? 1 : 0
77
81
push! (slots,slot (i,typ,width,option,locale))
78
82
push! (trans,tran)
79
83
end
@@ -82,18 +86,18 @@ function DateFormat(f::String,locale::String="english")
82
86
end
83
87
84
88
const SLOTERROR = ArgumentError (" Non-digit character encountered" )
85
- slotparse (slot,x) = ! ismatch (r" \D " ,x) ? slot. period (x) : throw (SLOTERROR)
89
+ slotparse (slot,x) = ! ismatch (r" [^0-9 \s ] " ,x) ? slot. period (x) : throw (SLOTERROR)
86
90
function slotparse (slot:: Slot{Month} ,x)
87
91
if slot. option == 0
88
- ismatch (r" \D " ,x) && throw (SLOTERROR)
89
- return Month (x)
92
+ ismatch (r" [^0-9\s ]" ,x) ? throw (SLOTERROR) : return Month (x)
90
93
elseif slot. option == 1
91
94
return Month (MONTHTOVALUEABBR[slot. locale][lowercase (x)])
92
95
else
93
96
return Month (MONTHTOVALUE[slot. locale][lowercase (x)])
94
97
end
95
98
end
96
- slotparse (slot:: Slot{Millisecond} ,x) = ! ismatch (r" \D " ,x) ? slot. period (parsefloat (" ." * x)* 1000.0 ) : throw (SLOTERROR)
99
+ slotparse (slot:: Slot{Millisecond} ,x) = ! ismatch (r" [^0-9\s ]" ,x) ? slot. period (parsefloat (" ." * x)* 1000.0 ) : throw (SLOTERROR)
100
+ slotparse (slot:: Slot{DayOfWeekSlot} ,x) = nothing
97
101
98
102
function getslot (x,slot:: DelimitedSlot ,df,cursor)
99
103
endind = first (search (x,df. trans[slot. i],cursor+ 1 ))
@@ -108,13 +112,13 @@ getslot(x,slot,df,cursor) = (cursor+slot.width, slotparse(slot,x[cursor:(cursor+
108
112
function parse (x:: String ,df:: DateFormat )
109
113
x = strip (replace (x, r" #.*$" , " " ))
110
114
x = replace (x,df. begtran," " )
111
- isempty (x) && throw (ArgumentError (" Cannot parse empty string" ))
115
+ isempty (x) && throw (ArgumentError (" Cannot parse empty format string" ))
112
116
(typeof (df. slots[1 ]) <: DelimitedSlot && first (search (x,df. trans[1 ])) == 0 ) && throw (ArgumentError (" Delimiter mismatch. Couldn't find first delimiter, \" $(df. trans[1 ]) \" , in date string" ))
113
117
periods = Period[]
114
118
cursor = 1
115
119
for slot in df. slots
116
120
cursor, pe = getslot (x,slot,df,cursor)
117
- push! (periods,pe)
121
+ pe != nothing && push! (periods,pe)
118
122
cursor > endof (x) && break
119
123
end
120
124
return sort! (periods,rev= true ,lt= periodisless)
@@ -131,6 +135,13 @@ function slotformat(slot::Slot{Month},dt)
131
135
return VALUETOMONTH[slot. locale][month (dt)]
132
136
end
133
137
end
138
+ function slotformat (slot:: Slot{DayOfWeekSlot} ,dt)
139
+ if slot. option == 1
140
+ return VALUETODAYOFWEEKABBR[slot. locale][dayofweek (dt)]
141
+ else # == 2
142
+ return VALUETODAYOFWEEK[slot. locale][dayofweek (dt)]
143
+ end
144
+ end
134
145
slotformat (slot:: Slot{Millisecond} ,dt) = rpad (string (millisecond (dt)/ 1000.0 )[3 : end ], slot. width, " 0" )
135
146
136
147
function format (dt:: TimeType ,df:: DateFormat )
145
156
# UI
146
157
const ISODateTimeFormat = DateFormat (" yyyy-mm-ddTHH:MM:SS.s" )
147
158
const ISODateFormat = DateFormat (" yyyy-mm-dd" )
159
+ const RFC1123Format = DateFormat (" e, dd u yyyy HH:MM:SS" )
148
160
149
161
DateTime (dt:: String ,format:: String ;locale:: String = " english" ) = DateTime (dt,DateFormat (format,locale))
150
162
DateTime (dt:: String ,df:: DateFormat = ISODateTimeFormat) = DateTime (parse (dt,df)... )
0 commit comments