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

Reply via email to