class: Timestamp
authorClaus Gittinger <cg@exept.de>
Fri, 07 Nov 2014 13:12:29 +0100
changeset 16955 2c49b8f7fc7f
parent 16954 e13618117ebc
child 16956 cb73613436ab
class: Timestamp comment/format in: #documentation #year:month:day:hour:minute:second:millisecond: changed: #printOn: #utcOffsetFrom: #utcOffsetFromString:
Timestamp.st
--- a/Timestamp.st	Fri Nov 07 13:12:01 2014 +0100
+++ b/Timestamp.st	Fri Nov 07 13:12:29 2014 +0100
@@ -53,8 +53,9 @@
 "
     This class represents time values in milliSeconds starting some time in the past.
     When printing and accessing values like #hour,
-    the timestamp will be interpreted in the local timezone (as opposed to UtcTimestamp,
-    which presents itself in UTC.
+    the timestamp will be interpreted in the local timezone 
+    (as opposed to UtcTimestamp, which presents itself in UTC,
+     and as opposed to LocalTimestamp, which remembers the timezone in which it was created).
 
     The internal representation, osTime, will typically start with 1970-01-01 0:00,
     as used in the Unix operating system, but other systems may bias the time differently.
@@ -82,16 +83,16 @@
     AbsoluteTime is still kept as an alias for backward compatibility.
 
     Also Note:
-	On UNIX, osTime can only hold dates between 1970-01-01T00:00:00Z and 2038-01-19T00:00:00Z
-	However, timestamp instances can now hold negative osTime values (which are timestamps
-	before 1.1.1970 and greater than 4294967295 (2^32-1) for timestamps after 2038-01-19.
+        On UNIX, osTime can only hold dates between 1970-01-01T00:00:00Z and 2038-01-19T00:00:00Z
+        However, timestamp instances can now hold negative osTime values (which are timestamps
+        before 1.1.1970 and greater than 4294967295 (2^32-1) for timestamps after 2038-01-19.
 
     [author:]
-	Claus Gittinger
+        Claus Gittinger
 
     [See also:]
-	UtcTimestamp Time Date
-	Delay ProcessorScheduler
+        UtcTimestamp Time Date
+        Delay ProcessorScheduler
 "
 ! !
 
@@ -1359,142 +1360,145 @@
     |table i offset stream tzName sign|
 
     table :=
-	#(
-	    'GMT'   0
-	    'UTC'   0
-
-	    "/ US
-	    'AST'   -4                 "/ atlantic
-	    'ADT'   -3
-
-	    'AKST'   -8                "/ alaska
-	    'AKDT'   -9
-
-	    'CST'   -6                 "/ central
-	    'CDT'   -5
-
-	    'EST'   -5                 "/ eastern
-	    'EDT'   -4
-
-	    'EGST'   0                 "/ east greenland
-	    'EGT'   -1
-
-	    'HADT'   -9                "/ hawaii
-	    'HAST'   -10
-
-	    'MST'   -7                 "/ mountain
-	    'MDT'   -6
-
-	    'NST'   -3.5                 "/ new foundland
-	    'NDT'   -2.5
-
-	    'PST'   -8                 "/ pacific
-	    'PDT'   -7
-
-	    'PMST'  -3                 "/ pierre & miquelon
-	    'PMDT'  -2
-
-	    'WGST'  -2                 "/ west greenland
-	    'WGT'   -3
-
-	    "/ europe
-	    'CET'   1                 "/ central european
-	    'CEST'  2
-
-	    'EET'   2                 "/ east european
-	    'EEST'  3
-
-	    'WET'   0                  "/ west european
-	    'WEST'  1
-
-	    'MSK'   4                  "/ moscow european
-	    'MSD'   4
-
-	    "/ pacific
-	    'NZST' 12                 "/ new zealand
-	    'NZDT' 13
-
-	    "/ south america
-	    'ART'   -3                 "/ argentina
-	    'BOT'   -4                 "/ bolivia
-	    'BRT'   -3                 "/ brasilia
-	    'BRST'  -2
-	    'CLT'   -4                 "/ chile
-	    'CLST'  -3
-	    'ECT'   -5                 "/ equador
-	    'PET'   -5                 "/ peru
-	    'PYT'   -4                 "/ paraguay
-	    'UYT'   -3                 "/ uruguay
-	    'VET'   -4.5               "/ venezuela
-
-	    "/ africa
-	    'CAT'   2                 "/ central africa
-	    'EAT'   3                 "/ east africa
-	    'SAST'  2                 "/ south africa
-	    'WAT'   1                 "/ west africa
-	    'WAST'  2
-	    'WT'    0                  "/ west sahara
-	    'WST'   1
-
-	    'HKT'   8                 "/ hongkong
-	    'IST'   5.5                "/ india
-	    'JST'   9                 "/ japan
-	    'KST'   9                 "/ korea
-	    'SGT'   8                 "/ singapore
-
-	    "/ military
-	    'A'     1
-	    'B'     2
-	    'C'     3
-	    'D'     4
-	    'E'     5
-	    'F'     6
-	    'G'     7
-	    'H'     8
-	    'I'     9
-	    'K'     10
-	    'L'     11
-	    'M'     12
-	    'N'     -1
-	    'O'     -2
-	    'P'     -3
-	    'Q'     -4
-	    'R'     -5
-	    'S'     -6
-	    'T'     -7
-	    'U'     -8
-	    'V'     -9
-	    'W'     -10
-	    'X'     -11
-	    'Y'     -12
-	).
+        #(
+            'GMT'   0
+            'UTC'   0
+
+            "/ US
+            'AST'   -4                 "/ atlantic
+            'ADT'   -3
+
+            'AKST'   -8                "/ alaska
+            'AKDT'   -9
+
+            'CST'   -6                 "/ central
+            'CDT'   -5
+
+            'EST'   -5                 "/ eastern
+            'EDT'   -4
+
+            'EGST'   0                 "/ east greenland
+            'EGT'   -1
+
+            'HADT'   -9                "/ hawaii
+            'HAST'   -10
+
+            'MST'   -7                 "/ mountain
+            'MDT'   -6
+
+            'NST'   -3.5                 "/ new foundland
+            'NDT'   -2.5
+
+            'PST'   -8                 "/ pacific
+            'PDT'   -7
+
+            'PMST'  -3                 "/ pierre & miquelon
+            'PMDT'  -2
+
+            'WGST'  -2                 "/ west greenland
+            'WGT'   -3
+
+            "/ europe
+            'CET'   1                 "/ central european
+            'CEST'  2
+
+            'EET'   2                 "/ east european
+            'EEST'  3
+
+            'WET'   0                  "/ west european
+            'WEST'  1
+
+            'MSK'   4                  "/ moscow european
+            'MSD'   4
+
+            "/ pacific
+            'NZST' 12                 "/ new zealand
+            'NZDT' 13
+
+            "/ south america
+            'ART'   -3                 "/ argentina
+            'BOT'   -4                 "/ bolivia
+            'BRT'   -3                 "/ brasilia
+            'BRST'  -2
+            'CLT'   -4                 "/ chile
+            'CLST'  -3
+            'ECT'   -5                 "/ equador
+            'PET'   -5                 "/ peru
+            'PYT'   -4                 "/ paraguay
+            'UYT'   -3                 "/ uruguay
+            'VET'   -4.5               "/ venezuela
+
+            "/ africa
+            'CAT'   2                 "/ central africa
+            'EAT'   3                 "/ east africa
+            'SAST'  2                 "/ south africa
+            'WAT'   1                 "/ west africa
+            'WAST'  2
+            'WT'    0                  "/ west sahara
+            'WST'   1
+
+            'HKT'   8                 "/ hongkong
+            'IST'   5.5                "/ india
+            'JST'   9                 "/ japan
+            'KST'   9                 "/ korea
+            'SGT'   8                 "/ singapore
+
+            "/ military
+            'A'     1
+            'B'     2
+            'C'     3
+            'D'     4
+            'E'     5
+            'F'     6
+            'G'     7
+            'H'     8
+            'I'     9
+            'K'     10
+            'L'     11
+            'M'     12
+            'N'     -1
+            'O'     -2
+            'P'     -3
+            'Q'     -4
+            'R'     -5
+            'S'     -6
+            'T'     -7
+            'U'     -8
+            'V'     -9
+            'W'     -10
+            'X'     -11
+            'Y'     -12
+        ).
 
     stream := aStringOrStream readStream.
     stream skipSeparators.
 
     stream peek isLetter ifTrue:[
-	tzName := stream upToElementForWhich:[:ch | ch isLetter not].
-
-	i := table indexOf:tzName.
-	i ~~ 0 ifTrue:[
-	    ^ (table at:i+1) * 60 * 60
-	].
+        tzName := stream upToElementForWhich:[:ch | ch isLetter not].
+
+        i := table indexOf:tzName.
+        i ~~ 0 ifTrue:[
+            ^ (table at:i+1) * 60 * 60
+        ].
     ] ifFalse:[
-	sign := 1.
-	stream peek == $- ifTrue:[
-	    sign := -1.
-	    stream next.
-	] ifFalse:[
-	    stream peek == $+ ifTrue:[
-		sign := 1.
-		stream next.
-	    ] ifFalse:[
-		stream skipSeparators
-	    ]
-	].
-	offset := ((stream next:2) asNumber * 60 * 60).
-	offset := offset + ((stream next:2) asNumber * 60).
-	^  offset * sign
+        sign := 1.
+        stream peek == $- ifTrue:[
+            sign := -1.
+            stream next.
+        ] ifFalse:[
+            stream peek == $+ ifTrue:[
+                sign := 1.
+                stream next.
+            ] ifFalse:[
+                stream skipSeparators
+            ]
+        ].
+        offset := ((stream next:2) asNumber * 60 * 60).
+        stream peekOrNil notNil ifTrue:[
+            stream peek == $: ifTrue:[ stream next ].
+            offset := offset + ((stream next:2) asNumber * 60).
+        ].
+        ^ offset * sign
     ].
 
     ^ nil
@@ -1504,142 +1508,21 @@
      self utcOffsetFrom:'PST'
      self utcOffsetFrom:'EST'
      self utcOffsetFrom:'+0130'
+     self utcOffsetFrom:'+01:30'
+     self utcOffsetFrom:'+01'
     "
 !
 
 utcOffsetFromString:aString
+    <resource: #obsolete>
     "return the utcOffset (in seconds) for a given time-zone name.
      Returns nil for invalid formats"
 
-    |table i offset|
-
-    table :=
-	#(
-	    'GMT'   0
-	    'UTC'   0
-
-	    "/ US
-	    'AST'   -4                 "/ atlantic
-	    'ADT'   -3
-
-	    'AKST'   -8                "/ alaska
-	    'AKDT'   -9
-
-	    'CST'   -6                 "/ central
-	    'CDT'   -5
-
-	    'EST'   -5                 "/ eastern
-	    'EDT'   -4
-
-	    'EGST'   0                 "/ east greenland
-	    'EGT'   -1
-
-	    'HADT'   -9                "/ hawaii
-	    'HAST'   -10
-
-	    'MST'   -7                 "/ mountain
-	    'MDT'   -6
-
-	    'NST'   -3.5                 "/ new foundland
-	    'NDT'   -2.5
-
-	    'PST'   -8                 "/ pacific
-	    'PDT'   -7
-
-	    'PMST'  -3                 "/ pierre & miquelon
-	    'PMDT'  -2
-
-	    'WGST'  -2                 "/ west greenland
-	    'WGT'   -3
-
-	    "/ europe
-	    'CET'   1                 "/ central european
-	    'CEST'  2
-
-	    'EET'   2                 "/ east european
-	    'EEST'  3
-
-	    'WET'   0                  "/ west european
-	    'WEST'  1
-
-	    'MSK'   4                  "/ moscow european
-	    'MSD'   4
-
-	    "/ pacific
-	    'NZST' 12                 "/ new zealand
-	    'NZDT' 13
-
-	    "/ south america
-	    'ART'   -3                 "/ argentina
-	    'BOT'   -4                 "/ bolivia
-	    'BRT'   -3                 "/ brasilia
-	    'BRST'  -2
-	    'CLT'   -4                 "/ chile
-	    'CLST'  -3
-	    'ECT'   -5                 "/ equador
-	    'PET'   -5                 "/ peru
-	    'PYT'   -4                 "/ paraguay
-	    'UYT'   -3                 "/ uruguay
-	    'VET'   -4.5               "/ venezuela
-
-	    "/ africa
-	    'CAT'   2                 "/ central africa
-	    'EAT'   3                 "/ east africa
-	    'SAST'  2                 "/ south africa
-	    'WAT'   1                 "/ west africa
-	    'WAST'  2
-	    'WT'    0                  "/ west sahara
-	    'WST'   1
-
-	    'HKT'   8                 "/ hongkong
-	    'IST'   5.5                "/ india
-	    'JST'   9                 "/ japan
-	    'KST'   9                 "/ korea
-	    'SGT'   8                 "/ singapore
-
-	    "/ military
-	    'A'     1
-	    'B'     2
-	    'C'     3
-	    'D'     4
-	    'E'     5
-	    'F'     6
-	    'G'     7
-	    'H'     8
-	    'I'     9
-	    'K'     10
-	    'L'     11
-	    'M'     12
-	    'N'     -1
-	    'O'     -2
-	    'P'     -3
-	    'Q'     -4
-	    'R'     -5
-	    'S'     -6
-	    'T'     -7
-	    'U'     -8
-	    'V'     -9
-	    'W'     -10
-	    'X'     -11
-	    'Y'     -12
-	).
-
-    i := table indexOf:aString.
-    i ~~ 0 ifTrue:[ ^ (table at:i+1) * 60 * 60 ].
-
-    aString size == 5 ifTrue:[
-	offset := (aString copyFrom:4 to:5) asNumber * 60.
-	offset := offset + ((offset copyFrom:2 to:3) asNumber * 60 * 60).
-	(aString at:1) == $- ifTrue:[
-	    offset := offset negated.
-	].
-	^  offset
-    ].
-
-    ^ nil
+    ^ self utcOffsetFrom:aString
 
     "
-     self utcOffsetFrom:'UTC'
+     self utcOffsetFromString:'UTC'  
+     self utcOffsetFromString:'+01'  
     "
 ! !
 
@@ -2199,18 +2082,18 @@
 
 year:y month:m day:d hour:h minute:min second:s millisecond:millis
     Error handle:[:ex |
-	"handler for timestamps before the epoch or after the OS representable time (2038 on current Unices).
-	 Then, an out-of-os-reange osTime is generated here manually."
-
-	|deltaDays|
-
-	deltaDays := self class epoch asDate subtractDate:(Date newDay:d month:m year:y).
-	"/ deltadays will be negative for dates before the epoch and positive if after.
-
-	osTime := (((h * 3600) + (min * 60) + s) * 1000) + millis.
-	osTime := osTime - (deltaDays * 24 * 3600 * 1000).
+        "handler for timestamps before the epoch or after the OS representable time (2038 on current Unices).
+         Then, an out-of-os-range osTime is generated here manually."
+
+        |deltaDays|
+
+        deltaDays := self class epoch asDate subtractDate:(Date newDay:d month:m year:y).
+        "/ deltadays will be negative for dates before the epoch and positive if after.
+
+        osTime := (((h * 3600) + (min * 60) + s) * 1000) + millis.
+        osTime := osTime - (deltaDays * 24 * 3600 * 1000).
     ] do:[
-	self setOSTimeFromYear:y month:m day:d hour:h minute:min second:s millisecond:millis
+        self setOSTimeFromYear:y month:m day:d hour:h minute:min second:s millisecond:millis
     ].
 ! !
 
@@ -2415,12 +2298,15 @@
      The format is compatible with readFromString:, but not with readFrom:."
 
     "/ now, use ISO format...
-    self printOn:aStream format:'%(year)-%(mon)-%(day) %h:%m:%s.%i'
+    self printIso8601FormatOn:aStream.
+"/    self printOn:aStream format:'%(year)-%(mon)-%(day) %h:%m:%s.%i'
 "/    self printOn:aStream format:'%(Day)-%(mon)-%(year) %h:%m:%s.%i'
 "/    self printOn:aStream format:'%(mon)/%(Day)/%(year) %h:%m:%s.%i'
 
     "
      Timestamp now printOn:Transcript. Transcript cr.
+     Timestamp now asUtcTimestamp printOn:Transcript. Transcript cr.
+
      (Timestamp fromSeconds:0) printOn:Transcript. Transcript cr.
      Time now printOn:Transcript. Transcript cr.
      Date today printOn:Transcript. Transcript cr.
@@ -2870,13 +2756,13 @@
 
 printAsLocalTime: aTimestamp on: aStream
     "Print the given timestamp in general ISO8601 format,
-     such as '2014-11-06T11:48:09Z'.
+     such as '2014-11-06T11:48:09+01'.
      The time is printed as local time"
 
     self print:aTimestamp compact:false asLocal:true withMilliseconds:true on:aStream
 
     "
-     self printAsLocalTime:(Timestamp now) on:Transcript
+     self printAsLocalTime:(Timestamp now) on:Transcript    
     "
 !
 
@@ -3108,8 +2994,8 @@
     isUtcTime := false.
 
     yearAlreadyRead ~~ true ifTrue:[
-	"Read the year. This will read and swallow up to four year digits."
-	self readYear.
+        "Read the year. This will read and swallow up to four year digits."
+        self readYear.
     ].
 
     "Check if date has been read, ie. T or space necountered. If yes, read the time.
@@ -3117,45 +3003,48 @@
     valid. But don't mind that, timestamps will be well-formatted in most cases."
     peek := stream peekOrNil.
     peek ifNil: [
-	"End of stream, only year has been read."
-	^self timestampWithClass:timestampClass].
-    peek = $- ifTrue: [
-	"Skip the dash after year, if present."
-	stream next.
-	peek := stream peekOrNil].
+        "End of stream, only year has been read."
+        ^ self timestampWithClass:timestampClass].
+    peek == $- ifTrue: [
+        "Skip the dash after year, if present."
+        stream next.
+        peek := stream peekOrNil].
     peek := peek asUppercase.
 
-    (peek = $T or: [peek = Character space])
-	ifTrue: [
-	    "Got time signature. Skip the signature, read time and answer the timestamp."
-	    stream next.
-	    self readTime.
-	    self readTimezone.
-	    ^ self timestampWithClass:timestampClass]
-	ifFalse: [
-	    "Date not read completely yet, expecting month/day or week/day or day"
-	    peek = $W
-		ifTrue: [
-		    "Parse week number and (possibly) day number."
-		    stream next.
-		    self readWeekNumber]
-		ifFalse: [
-		    "Got digit, read month number followed by day or day number."
-		    self readMonthOrDay]
-	].
+    (peek = $T or: [peek == Character space])
+        ifTrue: [
+            "Got time signature. Skip the signature, read time and answer the timestamp."
+            stream next.
+            peek == Character space ifTrue:[stream skipSeparators].
+            self readTime.
+            self readTimezone.
+            ^ self timestampWithClass:timestampClass
+        ] 
+        ifFalse: [
+            "Date not read completely yet, expecting month/day or week/day or day"
+            peek == $W
+                ifTrue: [
+                    "Parse week number and (possibly) day number."
+                    stream next.
+                    self readWeekNumber]
+                ifFalse: [
+                    "Got digit, read month number followed by day or day number."
+                    self readMonthOrDay]
+        ].
 
     peek := stream peekOrNil.
     peek ifNil: [
-	"End of stream, only year has been read."
-	^ self timestampWithClass:timestampClass].
-
-    (peek asUppercase = $T or: [peek = Character space])
-	ifTrue: [
-	    "Got time signature, expecting time follows. Otherwise only date was in the stream."
-	    stream next.
-	    self readTime.
-	    self readTimezone
-	].
+        "End of stream, only year has been read."
+        ^ self timestampWithClass:timestampClass].
+
+    (peek asUppercase == $T or: [peek == Character space])
+        ifTrue: [
+            "Got time signature, expecting time follows. Otherwise only date was in the stream."
+            stream next.
+            peek == Character space ifTrue:[stream skipSeparators].
+            self readTime.
+            self readTimezone
+        ].
 
     ^ self timestampWithClass:timestampClass
 
@@ -3494,11 +3383,11 @@
 !Timestamp class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.175 2014-11-06 22:18:06 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.176 2014-11-07 12:12:29 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.175 2014-11-06 22:18:06 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.176 2014-11-07 12:12:29 cg Exp $'
 ! !