Hi What are the expectation for DateAndTime>>readFrom?
On squeak such tests do not pass. testReadFromFoolProofExtension "Convenient extension without a time, only a date" "self debug: #testReadFromFoolProofExtension" self assert: ('2008' asDateAndTime printString = '2008-01-01T00:00:00+00:00'). self assert: ('2008-08' asDateAndTime printString = '2008-08-01T00:00:00+00:00'). self assert: ('2006-08-28' asDateAndTime printString = '2006-08-28T00:00:00+00:00'). "Regular nanoseconds" self assert: ('2006-08-28T00:00:00.123456789' asDateAndTime printString = '2006-08-28T00:00:00.123456789+00:00'). "Extra picoseconds precision should not spoil the DateAndTime" self assert: ('2006-08-28T00:00:00.123456789000' asDateAndTime printString = '2006-08-28T00:00:00.123456789+00:00'). in Pharo DateAndTime>>rreadFrom: aStream | bc year month day hour minute second nanos offset buffer ch | aStream peek = $- ifTrue: [ aStream next. bc := -1] ifFalse: [bc := 1]. year := (aStream upTo: $-) asInteger * bc. month := (aStream upTo: $-) asInteger ifNil: [1]. day := (aStream upTo: $T) asInteger ifNil: [1]. hour := (aStream upTo: $:) asInteger ifNil: [0]. buffer := '00:' copy. ch := nil. minute := buffer writeStream. [ aStream atEnd | (ch = $:) | (ch = $+) | (ch = $-) ] whileFalse: [ ch := minute nextPut: aStream next. ]. (ch isNil or: [ch isDigit]) ifTrue: [ ch := $: ]. minute := (buffer readStream upTo: ch) asInteger. buffer := '00.' copy. second := buffer writeStream. [ aStream atEnd | (ch = $.) | (ch = $+) | (ch = $-) ] whileFalse: [ ch := second nextPut: aStream next. ]. (ch isNil or: [ch isDigit]) ifTrue: [ ch := $. ]. second := (buffer readStream upTo: ch) asInteger. buffer := '000000000' copy. (ch = $.) ifTrue: [ nanos := buffer writeStream. [ aStream atEnd | ((ch := aStream next) = $+) | (ch = $-) ] whileFalse: [ nanos nextPut: ch. ]. (ch isNil or: [ch isDigit]) ifTrue: [ ch := $+ ]. ]. nanos := buffer asInteger. aStream atEnd ifTrue: [ offset := Duration zero ] ifFalse: [ch := aStream next. ch = $+ ifTrue: [ch := Character space]. offset := Duration fromString: ch asString, '0:', aStream upToEnd, ':0']. ^ self year: year month: month day: day hour: hour minute: minute second: second nanoSecond: nanos offset: offset. It loosk a bit ugly and crashed on some inputs In Squeak they have code that looks cleaner readFrom: aStream | offset date time ch | date := Date readFrom: aStream. [aStream peek isDigit] whileFalse: [aStream next]. time := Time readFrom: aStream. aStream atEnd ifTrue: [ offset := Duration zero ] ifFalse: [ ch := aStream next. ch = $+ ifTrue: [ch := Character space]. offset := Duration fromString: ch asString, '0:', aStream upToEnd, ':0']. ^ self year: date year month: date monthIndex day: date dayOfMonth hour: time hour minute: time minute second: time second nanoSecond: time nanoSecond offset: offset Date ============================================================ For Date we have readFrom: aStream readFrom: pattern: "Read a Date from the stream in any of the forms: <day> <month> <year> (15 April 1982; 15-APR-82; 15.4.82; 15APR82) <month> <day> <year> (April 15, 1982; 4/15/82) Squeak has a better one readFrom: pattern: "Read a Date from the stream in any of the forms: <day> <month> <year> (15 April 1982; 15-APR-82; 15.4.82; 15APR82) <month> <day> <year> (April 15, 1982; 4/15/82) <year>-<month>-<day> (1982-04-15) (ISO8601)" I like the idea to have a readFrom: that is parsing a specific input and that the variations are handled in separate methods. So for DateAndTime we coudl have fuzzyReadFrom: aStream or something like that. Duration ====================================================== Now for Duration readFrom: the pattern is strictly followed "Formatted as per ANSI 5.8.2.16: [-]D:HH:MM:SS[.S]" In pharo it was bogus. So I was considering the one of Squeak, which looks cleaner. Pharo broke for (Duration readFrom: '0:00:00:00.001 ' readStream) nanoSeconds Squeak>>readFrom: aStream "Formatted as per ANSI 5.8.2.16: [-]D:HH:MM:SS[.S]" | sign days hours minutes seconds nanos nanosBuffer | sign := (aStream peekFor: $-) ifTrue: [-1] ifFalse: [1]. days := (aStream upTo: $:) asInteger sign: sign. hours := (aStream upTo: $:) asInteger sign: sign. minutes := (aStream upTo: $:) asInteger sign: sign. seconds := (aStream upTo: $.) asInteger sign: sign. nanosBuffer := '000000000' copy. nanos := WriteStream on: nanosBuffer. [aStream atEnd not and: [aStream peek isDigit]] whileTrue: [nanos nextPut: aStream next]. ^ self days: days hours: hours minutes: minutes seconds: seconds nanoSeconds: (nanosBuffer asInteger sign: sign) Pharo>>readFrom: aStream "Formatted as per ANSI 5.8.2.16: [-]D:HH:MM:SS[.S] To assiste DateAndTime>>#readFrom: SS may be unpadded or absent." | sign days hours minutes seconds nanos ws ch | sign := (aStream peekFor: $-) ifTrue: [-1] ifFalse: [1]. days := (aStream upTo: $:) asInteger sign: sign. hours := (aStream upTo: $:) asInteger sign: sign. minutes := (aStream upTo: $:) asInteger sign: sign. aStream atEnd ifTrue: [seconds := 0. nanos := 0] ifFalse: [ ws := String new writeStream. [ch := aStream next. (ch isNil) | (ch = $.)] whileFalse: [ ws nextPut: ch ]. seconds := ws contents asInteger sign: sign. ws reset. 9 timesRepeat: [ ch := aStream next. ws nextPut: (ch ifNil: [$0] ifNotNil: [ch]) ]. nanos := ws contents asInteger sign: sign]. ^ self days: days hours: hours minutes: minutes seconds: seconds nanoSeconds: nanos. ====================================================== Stef _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project