Time.st
changeset 25221 4fcb818b33a1
parent 24118 02d39aaca894
--- a/Time.st	Thu Jan 30 21:10:04 2020 +0100
+++ b/Time.st	Thu Jan 30 21:10:53 2020 +0100
@@ -238,7 +238,7 @@
 
     |hour minute second millisecond
      utcOffset inStream formatStream error fChar format itemHandler
-     len s fraction fractionString|
+     len s fraction fractionString peekc|
 
     error := [:msg |
                 exceptionalValue isBlock ifTrue:[
@@ -276,18 +276,26 @@
             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' ]
+            input atEnd ifTrue:[
+                "/ am pm missing; assume 24 hr format
+                (hour between:0 and:24) ifFalse:[ error value:'invalid hour' ].
+                (hour = 24) ifTrue:[
+                    (minute > 0 or:[ second > 0 or:[ millisecond > 0 ]]) ifTrue:[ error value:'invalid hour' ].
+                    hour := 0.
+                ]
             ] ifFalse:[
-                s = 'pm' ifTrue:[
-                    (hour between:1 and:12) ifFalse:[ error value:'invalid hour' ].
-                    hour := hour + 12.
+                s := (input next:2) asLowercase.
+                s = 'am' ifTrue:[
+                    (hour between:0 and:12) ifFalse:[ error value:'invalid hour' ]
                 ] ifFalse:[
-                    error value:'invalid am/pm'
+                    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
         ]]]]]]]]
@@ -305,13 +313,15 @@
     [formatStream atEnd] whileFalse:[
         fChar := formatStream next.
         fChar = Character space ifTrue:[
-            inStream peek isSeparator ifFalse:[ error value: 'format error; space expcected' ].
-            inStream skipSeparators.
+            (peekc := inStream peek) notNil ifTrue:[
+                peekc isSeparator ifFalse:[ error value: 'space expcected' ].
+                inStream skipSeparators.
+            ]
         ] ifFalse:[
             fChar == $% ifTrue:[
                 len := nil.
                 (formatStream peek isDigit) ifTrue:[
-                    len := Integer readFrom:formatStream onError:[ error value: 'format error; invalid length' ]
+                    len := Integer readFrom:formatStream onError:[ error value: 'invalid length in time format' ]
                 ].
                 (formatStream peek == $() ifTrue:[
                     formatStream next.
@@ -357,12 +367,27 @@
 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
-     either 24 hour format or being am."
+     either 24 hour format or being am.
+     If it starts with T, assume iso8601 format"
 
     ^ [
-        |str hour min sec peekC millis|
+        |str hour min sec peekC millis pos tB ts|
 
         str := aStringOrStream readStream.
+        (str peek == $T) ifTrue:[
+            str next.
+            pos := str position.
+            Error handle:[:ex |
+                self halt.
+            ] do:[
+                tB := Timestamp::TimestampISO8601Builder new dateAlreadyReadAs:(Date today).
+                tB stream:str; readTime; readTimezone.
+                ts := tB timestampWithClass:Timestamp.
+                ^ ts asTime
+            ].
+            str position:pos.
+            ^ exceptionBlock value
+        ].
 
         hour := Integer readFrom:str.
         (hour between:0 and:24) ifFalse:[^ exceptionBlock value].
@@ -546,6 +571,8 @@
     ^ '%h:%m:%s.%i'
 ! !
 
+
+
 !Time methodsFor:'Compatibility-Backward'!
 
 asMilliSeconds
@@ -985,6 +1012,7 @@
 
      Time now printAsUTCIso8601FormatOn:Transcript. Transcript cr.
      Time now printIso8601FormatOn:Transcript. Transcript cr. 
+     Time now printIso8601CompressedOn:Transcript. Transcript cr. 
     "
 !
 
@@ -1187,6 +1215,7 @@
     timeEncoding := encoding
 ! !
 
+
 !Time methodsFor:'visiting'!
 
 acceptVisitor:aVisitor with:aParameter