182 |
180 |
183 ^ self fromSeconds: 43200 "12*60*60" |
181 ^ self fromSeconds: 43200 "12*60*60" |
184 |
182 |
185 " |
183 " |
186 Time noon |
184 Time noon |
|
185 " |
|
186 ! |
|
187 |
|
188 readFrom:aStringOrStream format:formatString language:languageOrNil onError:exceptionalValue |
|
189 "return a new Time, reading a printed representation from aStream using a formatString. |
|
190 The formatString is similar to the one used when printing. |
|
191 On error, exceptionalValue is returned. |
|
192 If exceptionalValue is a one-arg block, an error message is passed as argument. |
|
193 Format: |
|
194 %h hours, 00..23 (i.e. european) 0-padded to length 2 |
|
195 %u hours, 00..12 (i.e. us) 0-padded to length 2 |
|
196 %m minutes, 00..59 0-padded to length 2 |
|
197 %s seconds, 00..59 0-padded to length 2 |
|
198 %i milliseconds, 000..999 0-padded to length 3 |
|
199 %a am/pm |
|
200 |
|
201 an optional length after the % gives a field length; |
|
202 i.e. %2h%2m%2s parses '123557' as 12:35:37 |
|
203 |
|
204 Please consider using a standard format, such as iso8601. |
|
205 " |
|
206 |
|
207 |hour minute second millisecond |
|
208 utcOffset inStream formatStream error fChar format itemHandler |
|
209 len s| |
|
210 |
|
211 error := [:msg | |
|
212 exceptionalValue isBlock ifTrue:[ |
|
213 ^ exceptionalValue valueWithOptionalArgument:'format error' |
|
214 ] ifFalse:[ |
|
215 ^ exceptionalValue value |
|
216 ]. |
|
217 ]. |
|
218 |
|
219 itemHandler := [:format | |
|
220 |input| |
|
221 |
|
222 input := len isNil ifTrue:[ inStream ] ifFalse:[ inStream next: len ]. |
|
223 |
|
224 ( format = 'h' or:[ format = 'H' ]) ifTrue:[ |
|
225 hour := Integer readFrom:input onError:[ error value:'invalid hour' ]. |
|
226 |
|
227 ] ifFalse:[ ( format = 'u' or:[ format = 'U']) ifTrue:[ |
|
228 hour := Integer readFrom:input onError:[ error value:'invalid hour' ]. |
|
229 |
|
230 ] ifFalse:[ ( format = 'm' or:[ format = 'M' ]) ifTrue:[ |
|
231 minute := Integer readFrom:input onError:[ error value:'invalid minute' ]. |
|
232 |
|
233 ] ifFalse:[ ( format = 's' or:[ format = 'S' ]) ifTrue:[ |
|
234 second := Integer readFrom:input onError:[ error value:'invalid second' ]. |
|
235 |
|
236 ] ifFalse:[ ( format = 'i' or:[ format = 'I' ]) ifTrue:[ |
|
237 millisecond := Integer readFrom:input onError:[ error value:'invalid millsecond' ]. |
|
238 |
|
239 ] ifFalse:[ ( format = 'tz' ) ifTrue:[ |
|
240 utcOffset := Timestamp utcOffsetFrom:input. |
|
241 utcOffset isNil ifTrue:[ error value:'invalid timezone' ] |
|
242 ] ifFalse:[ ( format = 'a' ) ifTrue:[ |
|
243 s := (input next:2) asLowercase. |
|
244 s = 'am' ifTrue:[ |
|
245 (hour between:0 and:12) ifFalse:[ error value:'invalid hour' ] |
|
246 ] ifFalse:[ |
|
247 s = 'pm' ifTrue:[ |
|
248 (hour between:1 and:12) ifFalse:[ error value:'invalid hour' ]. |
|
249 hour := hour + 12. |
|
250 ] ifFalse:[ |
|
251 error value:'invalid am/pm' |
|
252 ] |
|
253 ] |
|
254 |
|
255 ] ifFalse:[ |
|
256 error value:'unhandled format:',format |
|
257 ]]]]]]] |
|
258 ]. |
|
259 |
|
260 hour := 0. |
|
261 minute := 0. |
|
262 second := 0. |
|
263 millisecond := 0. |
|
264 utcOffset := 0. |
|
265 |
|
266 inStream := aStringOrStream readStream. |
|
267 formatStream := formatString readStream. |
|
268 |
|
269 [formatStream atEnd] whileFalse:[ |
|
270 fChar := formatStream next. |
|
271 fChar = Character space ifTrue:[ |
|
272 inStream peek isSeparator ifFalse:[ error value: 'format error; space expcected' ]. |
|
273 inStream skipSeparators. |
|
274 ] ifFalse:[ |
|
275 fChar == $% ifTrue:[ |
|
276 len := nil. |
|
277 (formatStream peek isDigit) ifTrue:[ |
|
278 len := Integer readFrom:formatStream onError:[ error value: 'format error; invalid length' ] |
|
279 ]. |
|
280 (formatStream peek == $() ifTrue:[ |
|
281 formatStream next. |
|
282 format := formatStream upTo:$). |
|
283 ] ifFalse:[ |
|
284 (formatStream peek == ${) ifTrue:[ |
|
285 formatStream next. |
|
286 format := formatStream upTo:$}. |
|
287 ] ifFalse:[ |
|
288 (formatStream peek isLetter) ifTrue:[ |
|
289 format := formatStream nextAlphaNumericWord. |
|
290 ] ifFalse:[ |
|
291 error value:'unhandled format:',formatStream peek |
|
292 ] |
|
293 ] |
|
294 ]. |
|
295 itemHandler value:format. |
|
296 ] ifFalse:[ |
|
297 inStream peek = fChar ifFalse:[^ error value: 'format error; ',fChar,' expcected']. |
|
298 inStream next. |
|
299 ] |
|
300 ]. |
|
301 ]. |
|
302 |
|
303 ^ (self |
|
304 hours:(hour ? 0) minutes:(minute ? 0) seconds:(second ? 0) milliseconds:millisecond) |
|
305 + utcOffset |
|
306 |
|
307 " |
|
308 Time readFrom:'13:11:06' format:'%h:%m:%s' language:nil onError:[self halt] |
|
309 Time readFrom:'131106' format:'%2h%2m%2s' language:nil onError:[self halt] |
|
310 Time readFrom:'7:30pm EST' format:'%u:%m%a %tz' language:#en onError:[self halt] |
|
311 Time readFrom:'7:30pm UTC' format:'%u:%m%a %tz' language:#en onError:[self halt] |
187 " |
312 " |
188 ! |
313 ! |
189 |
314 |
190 readFrom:aStringOrStream onError:exceptionBlock |
315 readFrom:aStringOrStream onError:exceptionBlock |
191 "return a new Time, reading a printed representation from aStream. |
316 "return a new Time, reading a printed representation from aStream. |