class: Timestamp
added: #utcOffsetWithoutDst
changed:
#asDate
#asTime
#utcOffset
Fix for very large resp. very small dates in southern hemisphere
--- a/Timestamp.st Tue Nov 11 14:04:17 2014 +0100
+++ b/Timestamp.st Tue Nov 11 14:08:45 2014 +0100
@@ -1878,20 +1878,49 @@
"/ fake an info which the OS cannot give me
"/ we do not know about DST in the far future and in the long gone past.
"/ Take the utcOffset without DST
- ^ Epoch asLocalTimestamp utcOffset
+ ^ self utcOffsetWithoutDst.
].
^ (OperatingSystem computeTimeAndDateFrom:osTime) utcOffset
"
Timestamp now utcOffset
- (Timestamp day:1 month:7 year:1995 hour:12 minutes:0 seconds:0) utcOffset
+ (Timestamp year:1995 month:7 day:1 hour:12 minute:0 second:0) utcOffset
+ (Timestamp year:1995 month:1 day:1 hour:12 minute:0 second:0) utcOffset
+ (Timestamp year:1689 month:7 day:1 hour:12 minute:0 second:0) utcOffset
+ (Timestamp year:4096 month:7 day:1 hour:12 minute:0 second:0) utcOffset
"
"Modified: 20.12.1995 / 17:28:49 / stefan"
"Modified: 1.7.1996 / 15:21:29 / cg"
!
+utcOffsetWithoutDst
+ "return the difference between UTC (Greenwich Mean Time) and the local time in seconds.
+ If daylight saving time applies to ourself, do not take that into account.
+
+ Add utcOffset to convert from local time to UTC time.
+ Subtract utcOffset to convert from UTC time to local time.
+
+ If utcOffset is negative, the local timezone is east of Greenwich.
+ If utcOffset is positive, the local timezone is west of Greenwich."
+
+ |offset epochInfo|
+
+ offset := 0.
+ [
+ "DST may be in winter in the southern hemisphere. If we are in DST, add some days"
+ epochInfo := OperatingSystem timeInfoFromSeconds:offset milliseconds:0 localTime:true.
+ offset := offset + (3600 * 24 * 90). "Add about 3 months"
+ ] doWhile:[epochInfo dst and:[offset < (3600 * 24 * 365) "avoid endless loop"]].
+
+ ^ epochInfo utcOffset
+
+ "
+ Timestamp now utcOffsetWithoutDst
+ "
+!
+
weekInYear
"return the week number of the receiver - 1 for Jan, 1st."
@@ -2072,13 +2101,12 @@
otherwise if you convert an utcTimestamp, you'll get the utc date."
(osTime between:MinOSTime and:MaxOSTime) ifFalse:[
- |secondDelta dayDelta|
-
- secondDelta := osTime // 1000.
+ |milliDelta dayDelta|
+
"/ we do not know about DST in the far future and in the long gone past.
"/ Take the utcOffset without DST
- secondDelta := secondDelta - Epoch asLocalTimestamp utcOffset.
- dayDelta := secondDelta // (24 * 3600).
+ milliDelta := osTime - (1000 * self utcOffsetWithoutDst).
+ dayDelta := milliDelta // (24 * 3600 * 1000).
^ Epoch asDate addDays:dayDelta.
].
^ self timeInfo asDate
@@ -2185,7 +2213,7 @@
secondDelta := osTime // 1000.
"/ we do not know about DST in the far future and in the long gone past.
"/ Take the utcOffset without DST
- secondDelta := (secondDelta - Epoch asLocalTimestamp utcOffset) rem:(24*3600).
+ secondDelta := (secondDelta - self utcOffsetWithoutDst) \\ (24*3600).
^ Epoch asTime addSeconds:secondDelta.
].
^ self timeInfo asTime
@@ -3860,11 +3888,11 @@
!Timestamp class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.200 2014-11-11 12:12:44 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.201 2014-11-11 13:08:45 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.200 2014-11-11 12:12:44 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Timestamp.st,v 1.201 2014-11-11 13:08:45 stefan Exp $'
! !