I discovered a bug in
DateAndTime>>asParts which leads to date strings that look like 2010-04-20T14:02:60+00:00 (look at the seconds). What happens? In DateAndTime>>asParts ... x := seconds + offset. "seconds from base" array at: 7 put: x \\ 60. ... for a seconds value of 2.9346917950147009E+08 this is 2.9346917950147009E+08 \\ 60 = 5.9501470088958740E+01 finally in DateAndTime>>printOn: ... (x := array at: 7) < 10 ifTrue: [aStream nextPut: $0]. x rounded printOn: aStream. ... 5.9501470088958740E+01 rounded = 60 What would be a short term fix for this? Exchange rounded with asInteger? Norbert |
Norbert,
Here's new implementation of #asPart that gives the right answer: 2010-04-20T15:13:00+00:00 instead of 2010-04-20T15:12:60+00:00 I think this fix also takes care or the potential roundoff errors at the minutes, hours and day slots too by basically rounding x up to the nearest 60 seconds: asParts "#(year dayOfYear monthIndex dayOfMonth hour minute second)" | x y z array year isLeapYear numDaysArr | array := Array new: 7. x := seconds + offset. "seconds from base" z := x \\ 60. z rounded = 60 ifTrue: [ array at: 7 put: 0. x := x + (60 - (x \\ 60)) ] ifFalse: [ array at: 7 put: z ]. x := x // 60. "minutes from base" array at: 6 put: x \\ 60. x := x // 60. "hours from base" array at: 5 put: x \\ 24. x := x // 24. "days from base" year := 2001. y := x // 146097. year := y * 400 + year. x := x - (y * 146097). "days since beginning of 400-year cycle" y := x // 36524 min: 3. year := y * 100 + year. x := x - (y * 36524). "days since beginning of 100-year cycle" y := x // 1461 min: 96. year := y * 4 + year. x := x - (y * 1461). "days since beginning of 4-year cycle" y := x // 365 min: 3. year := y + year. x := x - (y * 365) + 1. "days since beginning of year" array at: 1 put: year; at: 2 put: x; yourself. x <= 31 ifTrue: [ ^array at: 3 put: 1; at: 4 put: x; yourself. ]. x <= 59 ifTrue: [ ^array at: 3 put: 2; at: 4 put: x - 31; yourself. ]. isLeapYear := year \\ 4 == 0 _and: [year \\ 100 ~~ 0 _or: [year \\ 400 == 0]]. isLeapYear ifTrue: [ x == 60 ifTrue: [ ^array at: 3 put: 2; at: 4 put: 29; yourself. ]. x := x - 1. ]. array at: 3 put: 3. x := x - 59. numDaysArr := #(31 30 31 30 31 31 30 31 30 31) . 1 to: numDaysArr size do:[:j | | each | each := numDaysArr at: j . x <= each ifTrue: [ ^array at: 4 put: x; yourself. ]. array at: 3 put: (array at: 3) + 1. x := x - each. ]. self error: 'invalid date'. |
I've submitted issue 84: http://code.google.com/p/glassdb/issues/detail?id=84 to track this issue...
Dale ----- "Dale Henrichs" <[hidden email]> wrote: | Norbert, | | Here's new implementation of #asPart that gives the right answer: | | 2010-04-20T15:13:00+00:00 | | instead of | | 2010-04-20T15:12:60+00:00 | | I think this fix also takes care or the potential roundoff errors at | the minutes, hours and day slots too by basically rounding x up to the | nearest 60 seconds: | | asParts | "#(year dayOfYear monthIndex dayOfMonth hour minute second)" | | | x y z array year isLeapYear numDaysArr | | array := Array new: 7. | x := seconds + offset. "seconds from base" | z := x \\ 60. | z rounded = 60 | ifTrue: [ | array at: 7 put: 0. | x := x + (60 - (x \\ 60)) ] | ifFalse: [ array at: 7 put: z ]. | x := x // 60. "minutes from base" | array at: 6 put: x \\ 60. | x := x // 60. "hours from base" | array at: 5 put: x \\ 24. | | x := x // 24. "days from base" | year := 2001. | | y := x // 146097. | year := y * 400 + year. | x := x - (y * 146097). "days since beginning of 400-year cycle" | | y := x // 36524 min: 3. | year := y * 100 + year. | x := x - (y * 36524). "days since beginning of 100-year cycle" | | y := x // 1461 min: 96. | year := y * 4 + year. | x := x - (y * 1461). "days since beginning of 4-year cycle" | | y := x // 365 min: 3. | year := y + year. | x := x - (y * 365) + 1. "days since beginning of year" | | array | at: 1 put: year; | at: 2 put: x; | yourself. | x <= 31 ifTrue: [ | ^array | at: 3 put: 1; | at: 4 put: x; | yourself. | ]. | x <= 59 ifTrue: [ | ^array | at: 3 put: 2; | at: 4 put: x - 31; | yourself. | ]. | isLeapYear := year \\ 4 == 0 _and: [year \\ 100 ~~ 0 _or: [year \\ | 400 == 0]]. | | isLeapYear ifTrue: [ | x == 60 ifTrue: [ | ^array | at: 3 put: 2; | at: 4 put: 29; | yourself. | ]. | x := x - 1. | ]. | array at: 3 put: 3. | x := x - 59. | | numDaysArr := #(31 30 31 30 31 31 30 31 30 31) . | 1 to: numDaysArr size do:[:j | | each | | each := numDaysArr at: j . | x <= each ifTrue: [ | ^array | at: 4 put: x; | yourself. | ]. | array at: 3 put: (array at: 3) + 1. | x := x - each. | ]. | self error: 'invalid date'. |
Free forum by Nabble | Edit this page |