Squeak dates are based on the Julian Day Number:
http://en.wikipedia.org/wiki/Julian_day This is defined as the number of days since January 1, 4713 BC in the Julian proleptic calendar. Now, to my surprise, Date julianDayNumber: 0 answers 24 November -4713 instead of 1 January -4712 Digging into this it is because Squeak uses the Fliegel-Van Flandern algorithm, which always results in a Gregorian date. Even for dates before the Gregorian calendar was introduced. If we were to use the algorithm by Jean Meeus, dates before 15 Nov 1582 would be converted to a Julian date. Meeus is a floating point algorithm which we may not want to use. I added a correction to our method similar to Meeus, but converted to integers. So this is a mixed one, pasted below. Would anyone be opposed to adopt this? The behavior will be unchanged for all dates more recent than 15 Nov 1582. If so, we also would need an adjustment for the reverse part in year:month:day:hour:minute:second:nanoSecond:offset:. This is already covered by a test using the year 1200 BC (DateAndTimeTest>>testFromString). Anybody up for making that work? I stumbled upon this because Etoys 5 has a new Calendar object which exposes the Julian Day Number, and setting it to 0 is a very convenient way of explaining what that means. Thanks! - Bert - dayMonthYearDo: aBlock "Evaluate the block with three arguments: day month, year. Uses the Fliegel-Van Flandern algorithm, with adjustment for dates before 15 Nov 1582 as given by Jean Meeus. See http://mathforum.org/library/drmath/view/51907.html" | a l n i j dd mm yyyy | a := jdn. a < 2299161 ifTrue: [ | alpha | alpha := (jdn * 4 - 7468865) // 146097. a := jdn - 1 - alpha + (alpha // 4)]. l := a + 68569. n := 4 * l // 146097. l := l - (146097 * n + 3 // 4). i := 4000 * (l + 1) // 1461001. l := l - (1461 * i // 4) + 31. j := 80 * l // 2447. dd := l - (2447 * j // 80). l := j // 11. mm := j + 2 - (12 * l). yyyy := 100 * (n - 49) + i + l. ^ aBlock value: dd value: mm value: yyyy |
On Mon, Jun 25, 2012 at 01:54:08PM +0200, Bert Freudenberg wrote:
> Squeak dates are based on the Julian Day Number: > > http://en.wikipedia.org/wiki/Julian_day > > This is defined as the number of days since January 1, 4713 BC in the Julian proleptic calendar. > > Now, to my surprise, > > Date julianDayNumber: 0 > > answers > > 24 November -4713 > > instead of > > 1 January -4712 > > Digging into this it is because Squeak uses the Fliegel-Van Flandern algorithm, which always results in a Gregorian date. Even for dates before the Gregorian calendar was introduced. If we were to use the algorithm by Jean Meeus, dates before 15 Nov 1582 would be converted to a Julian date. > > Meeus is a floating point algorithm which we may not want to use. I added a correction to our method similar to Meeus, but converted to integers. So this is a mixed one, pasted below. > > Would anyone be opposed to adopt this? The behavior will be unchanged for all dates more recent than 15 Nov 1582. I can't think of any reason why this should cause problems, aside from the need to make a couple of trivial updates to the unit tests. Perhaps Brent can comment, but it looks to me like a good thing to do. Dave > > If so, we also would need an adjustment for the reverse part in year:month:day:hour:minute:second:nanoSecond:offset:. This is already covered by a test using the year 1200 BC (DateAndTimeTest>>testFromString). Anybody up for making that work? > > I stumbled upon this because Etoys 5 has a new Calendar object which exposes the Julian Day Number, and setting it to 0 is a very convenient way of explaining what that means. > > Thanks! > > - Bert - > > dayMonthYearDo: aBlock > "Evaluate the block with three arguments: day month, year. > Uses the Fliegel-Van Flandern algorithm, with adjustment for dates before 15 Nov 1582 as given by Jean Meeus. > See http://mathforum.org/library/drmath/view/51907.html" > > | a l n i j dd mm yyyy | > a := jdn. > a < 2299161 ifTrue: [ | alpha | > alpha := (jdn * 4 - 7468865) // 146097. > a := jdn - 1 - alpha + (alpha // 4)]. > l := a + 68569. > n := 4 * l // 146097. > l := l - (146097 * n + 3 // 4). > i := 4000 * (l + 1) // 1461001. > l := l - (1461 * i // 4) + 31. > j := 80 * l // 2447. > dd := l - (2447 * j // 80). > l := j // 11. > mm := j + 2 - (12 * l). > yyyy := 100 * (n - 49) + i + l. > > ^ aBlock > value: dd > value: mm > value: yyyy > |
Great that Squeak will be in the position to calculate historical
dates properly, so no objection at all. Thank you for your careful analysis and a synthesis of an algorithm which corrects the problem. I assume you description will be in a class comment... Hannes On 6/25/12, David T. Lewis <[hidden email]> wrote: > On Mon, Jun 25, 2012 at 01:54:08PM +0200, Bert Freudenberg wrote: >> Squeak dates are based on the Julian Day Number: >> >> http://en.wikipedia.org/wiki/Julian_day >> >> This is defined as the number of days since January 1, 4713 BC in the >> Julian proleptic calendar. >> >> Now, to my surprise, >> >> Date julianDayNumber: 0 >> >> answers >> >> 24 November -4713 >> >> instead of >> >> 1 January -4712 >> >> Digging into this it is because Squeak uses the Fliegel-Van Flandern >> algorithm, which always results in a Gregorian date. Even for dates before >> the Gregorian calendar was introduced. If we were to use the algorithm by >> Jean Meeus, dates before 15 Nov 1582 would be converted to a Julian date. >> >> Meeus is a floating point algorithm which we may not want to use. I added >> a correction to our method similar to Meeus, but converted to integers. So >> this is a mixed one, pasted below. >> >> Would anyone be opposed to adopt this? The behavior will be unchanged for >> all dates more recent than 15 Nov 1582. > > I can't think of any reason why this should cause problems, aside from the > need to make a couple of trivial updates to the unit tests. Perhaps Brent > can comment, but it looks to me like a good thing to do. > > Dave > > >> >> If so, we also would need an adjustment for the reverse part in >> year:month:day:hour:minute:second:nanoSecond:offset:. This is already >> covered by a test using the year 1200 BC >> (DateAndTimeTest>>testFromString). Anybody up for making that work? >> >> I stumbled upon this because Etoys 5 has a new Calendar object which >> exposes the Julian Day Number, and setting it to 0 is a very convenient >> way of explaining what that means. >> >> Thanks! >> >> - Bert - >> >> dayMonthYearDo: aBlock >> "Evaluate the block with three arguments: day month, year. >> Uses the Fliegel-Van Flandern algorithm, with adjustment for dates before >> 15 Nov 1582 as given by Jean Meeus. >> See http://mathforum.org/library/drmath/view/51907.html" >> >> | a l n i j dd mm yyyy | >> a := jdn. >> a < 2299161 ifTrue: [ | alpha | >> alpha := (jdn * 4 - 7468865) // 146097. >> a := jdn - 1 - alpha + (alpha // 4)]. >> l := a + 68569. >> n := 4 * l // 146097. >> l := l - (146097 * n + 3 // 4). >> i := 4000 * (l + 1) // 1461001. >> l := l - (1461 * i // 4) + 31. >> j := 80 * l // 2447. >> dd := l - (2447 * j // 80). >> l := j // 11. >> mm := j + 2 - (12 * l). >> yyyy := 100 * (n - 49) + i + l. >> >> ^ aBlock >> value: dd >> value: mm >> value: yyyy >> > > |
If you need to calculates dates in different calendars, the reference is I have a literate programming based implementation in Python (an original Lisp code of tge book side by side) at [2]. A Smaltalk implenentation is available at [3]. HTH [1] http://emr.cs.iit.edu/home/reingold/calendar-book/third-edition/index.html On Jun 26, 2012 7:07 PM, "H. Hirzel" <[hidden email]> wrote:
Great that Squeak will be in the position to calculate historical |
Hi Enrico,
The Chronology package in Squeak takes a simple point of view in that only one calender algorithm is in effect. Based on your experience with this topic, would you say that the algorithm that Bert has proposed is a good choice? It seems to me that it is an improvement because it produces the expected results for a wide range of users, and it does not break any existing assumptions in the system. Thanks Dave On Tue, Jun 26, 2012 at 10:18:56PM +0200, Enrico Spinielli wrote: > If you need to calculates dates in different calendars, the reference is > Nachum Dershowitz, Edward M. Reingold 'Calendrical Calculations' [1]. > But beware of what you mean with 'historical' conversions: Gregorian > calendar was adopted at different times in different countries... > > I have a literate programming based implementation in Python (an original > Lisp code of tge book side by side) at [2]. > > A Smaltalk implenentation is available at [3]. > > HTH > Bye > Enrico > > [1] > http://emr.cs.iit.edu/home/reingold/calendar-book/third-edition/index.html > [2] http://code.google.com/p/pycalcal/ > [3] http://www.squeaksource.com/Calendrica.html > On Jun 26, 2012 7:07 PM, "H. Hirzel" <[hidden email]> wrote: > > > Great that Squeak will be in the position to calculate historical > > dates properly, so no objection at all. > > > > Thank you for your careful analysis and a synthesis of an algorithm > > which corrects the problem. I assume you description will be in a > > class comment... > > > > Hannes > > > > On 6/25/12, David T. Lewis <[hidden email]> wrote: > > > On Mon, Jun 25, 2012 at 01:54:08PM +0200, Bert Freudenberg wrote: > > >> Squeak dates are based on the Julian Day Number: > > >> > > >> http://en.wikipedia.org/wiki/Julian_day > > >> > > >> This is defined as the number of days since January 1, 4713 BC in the > > >> Julian proleptic calendar. > > >> > > >> Now, to my surprise, > > >> > > >> Date julianDayNumber: 0 > > >> > > >> answers > > >> > > >> 24 November -4713 > > >> > > >> instead of > > >> > > >> 1 January -4712 > > >> > > >> Digging into this it is because Squeak uses the Fliegel-Van Flandern > > >> algorithm, which always results in a Gregorian date. Even for dates > > before > > >> the Gregorian calendar was introduced. If we were to use the algorithm > > by > > >> Jean Meeus, dates before 15 Nov 1582 would be converted to a Julian > > date. > > >> > > >> Meeus is a floating point algorithm which we may not want to use. I > > added > > >> a correction to our method similar to Meeus, but converted to integers. > > So > > >> this is a mixed one, pasted below. > > >> > > >> Would anyone be opposed to adopt this? The behavior will be unchanged > > for > > >> all dates more recent than 15 Nov 1582. > > > > > > I can't think of any reason why this should cause problems, aside from > > the > > > need to make a couple of trivial updates to the unit tests. Perhaps Brent > > > can comment, but it looks to me like a good thing to do. > > > > > > Dave > > > > > > > > >> > > >> If so, we also would need an adjustment for the reverse part in > > >> year:month:day:hour:minute:second:nanoSecond:offset:. This is already > > >> covered by a test using the year 1200 BC > > >> (DateAndTimeTest>>testFromString). Anybody up for making that work? > > >> > > >> I stumbled upon this because Etoys 5 has a new Calendar object which > > >> exposes the Julian Day Number, and setting it to 0 is a very convenient > > >> way of explaining what that means. > > >> > > >> Thanks! > > >> > > >> - Bert - > > >> > > >> dayMonthYearDo: aBlock > > >> "Evaluate the block with three arguments: day month, year. > > >> Uses the Fliegel-Van Flandern algorithm, with adjustment for dates > > before > > >> 15 Nov 1582 as given by Jean Meeus. > > >> See http://mathforum.org/library/drmath/view/51907.html" > > >> > > >> | a l n i j dd mm yyyy | > > >> a := jdn. > > >> a < 2299161 ifTrue: [ | alpha | > > >> alpha := (jdn * 4 - 7468865) // 146097. > > >> a := jdn - 1 - alpha + (alpha // 4)]. > > >> l := a + 68569. > > >> n := 4 * l // 146097. > > >> l := l - (146097 * n + 3 // 4). > > >> i := 4000 * (l + 1) // 1461001. > > >> l := l - (1461 * i // 4) + 31. > > >> j := 80 * l // 2447. > > >> dd := l - (2447 * j // 80). > > >> l := j // 11. > > >> mm := j + 2 - (12 * l). > > >> yyyy := 100 * (n - 49) + i + l. > > >> > > >> ^ aBlock > > >> value: dd > > >> value: mm > > >> value: yyyy > > >> > > > > > > > > > > > |
I personally think that the initial confusion comes from the fact that we name a GregorianDate as Date. Once that is made explicit there is no surprise in writing: In my little Calendrica project I made that distinction explicit but the implicit convention of understanding Date being GregorianDate is equally valid. HTH On Jun 26, 2012 10:39 PM, "David T. Lewis" <[hidden email]> wrote:
Hi Enrico, |
Free forum by Nabble | Edit this page |