--- a/Time.st Sat Jun 06 06:39:31 2015 +0200
+++ b/Time.st Sun Jun 07 06:38:49 2015 +0200
@@ -1,5 +1,3 @@
-"{ Encoding: utf8 }"
-
"
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
@@ -187,6 +185,133 @@
"
!
+readFrom:aStringOrStream format:formatString language:languageOrNil onError:exceptionalValue
+ "return a new Time, reading a printed representation from aStream using a formatString.
+ The formatString is similar to the one used when printing.
+ On error, exceptionalValue is returned.
+ If exceptionalValue is a one-arg block, an error message is passed as argument.
+ Format:
+ %h hours, 00..23 (i.e. european) 0-padded to length 2
+ %u hours, 00..12 (i.e. us) 0-padded to length 2
+ %m minutes, 00..59 0-padded to length 2
+ %s seconds, 00..59 0-padded to length 2
+ %i milliseconds, 000..999 0-padded to length 3
+ %a am/pm
+
+ an optional length after the % gives a field length;
+ i.e. %2h%2m%2s parses '123557' as 12:35:37
+
+ Please consider using a standard format, such as iso8601.
+ "
+
+ |hour minute second millisecond
+ utcOffset inStream formatStream error fChar format itemHandler
+ len s|
+
+ error := [:msg |
+ exceptionalValue isBlock ifTrue:[
+ ^ exceptionalValue valueWithOptionalArgument:'format error'
+ ] ifFalse:[
+ ^ exceptionalValue value
+ ].
+ ].
+
+ itemHandler := [:format |
+ |input|
+
+ input := len isNil ifTrue:[ inStream ] ifFalse:[ inStream next: len ].
+
+ ( format = 'h' or:[ format = 'H' ]) ifTrue:[
+ hour := Integer readFrom:input onError:[ error value:'invalid hour' ].
+
+ ] ifFalse:[ ( format = 'u' or:[ format = 'U']) ifTrue:[
+ hour := Integer readFrom:input onError:[ error value:'invalid hour' ].
+
+ ] ifFalse:[ ( format = 'm' or:[ format = 'M' ]) ifTrue:[
+ minute := Integer readFrom:input onError:[ error value:'invalid minute' ].
+
+ ] ifFalse:[ ( format = 's' or:[ format = 'S' ]) ifTrue:[
+ second := Integer readFrom:input onError:[ error value:'invalid second' ].
+
+ ] ifFalse:[ ( format = 'i' or:[ format = 'I' ]) ifTrue:[
+ millisecond := Integer readFrom:input onError:[ error value:'invalid millsecond' ].
+
+ ] ifFalse:[ ( format = 'tz' ) ifTrue:[
+ utcOffset := Timestamp utcOffsetFrom:input.
+ utcOffset isNil ifTrue:[ error value:'invalid timezone' ]
+ ] ifFalse:[ ( format = 'a' ) ifTrue:[
+ s := (input next:2) asLowercase.
+ s = 'am' ifTrue:[
+ (hour between:0 and:12) ifFalse:[ error value:'invalid hour' ]
+ ] ifFalse:[
+ s = 'pm' ifTrue:[
+ (hour between:1 and:12) ifFalse:[ error value:'invalid hour' ].
+ hour := hour + 12.
+ ] ifFalse:[
+ error value:'invalid am/pm'
+ ]
+ ]
+
+ ] ifFalse:[
+ error value:'unhandled format:',format
+ ]]]]]]]
+ ].
+
+ hour := 0.
+ minute := 0.
+ second := 0.
+ millisecond := 0.
+ utcOffset := 0.
+
+ inStream := aStringOrStream readStream.
+ formatStream := formatString readStream.
+
+ [formatStream atEnd] whileFalse:[
+ fChar := formatStream next.
+ fChar = Character space ifTrue:[
+ inStream peek isSeparator ifFalse:[ error value: 'format error; space expcected' ].
+ inStream skipSeparators.
+ ] ifFalse:[
+ fChar == $% ifTrue:[
+ len := nil.
+ (formatStream peek isDigit) ifTrue:[
+ len := Integer readFrom:formatStream onError:[ error value: 'format error; invalid length' ]
+ ].
+ (formatStream peek == $() ifTrue:[
+ formatStream next.
+ format := formatStream upTo:$).
+ ] ifFalse:[
+ (formatStream peek == ${) ifTrue:[
+ formatStream next.
+ format := formatStream upTo:$}.
+ ] ifFalse:[
+ (formatStream peek isLetter) ifTrue:[
+ format := formatStream nextAlphaNumericWord.
+ ] ifFalse:[
+ error value:'unhandled format:',formatStream peek
+ ]
+ ]
+ ].
+ itemHandler value:format.
+ ] ifFalse:[
+ inStream peek = fChar ifFalse:[^ error value: 'format error; ',fChar,' expcected'].
+ inStream next.
+ ]
+ ].
+ ].
+
+ ^ (self
+ hours:(hour ? 0) minutes:(minute ? 0) seconds:(second ? 0) milliseconds:millisecond)
+ + utcOffset
+
+ "
+ Time readFrom:'13:11:06' format:'%h:%m:%s' language:nil onError:[self halt]
+ Time readFrom:'131106' format:'%2h%2m%2s' language:nil onError:[self halt]
+ Time readFrom:'7:30pm EST' format:'%u:%m%a %tz' language:#en onError:[self halt]
+ Time readFrom:'7:30pm UTC' format:'%u:%m%a %tz' language:#en onError:[self halt]
+ "
+!
+
readFrom:aStringOrStream onError:exceptionBlock
"return a new Time, reading a printed representation from aStream.
If no am/pm follows the time, the string is interpreted as
@@ -707,7 +832,6 @@
"
! !
-
!Time methodsFor:'printing & storing'!
print12HourFormatOn:aStream
@@ -953,10 +1077,10 @@
!Time class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Time.st,v 1.103 2015-03-24 07:20:13 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Time.st,v 1.104 2015-06-06 12:57:19 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/Time.st,v 1.103 2015-03-24 07:20:13 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Time.st,v 1.104 2015-06-06 12:57:19 cg Exp $'
! !