Julian dates

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Julian dates

Bert Freudenberg
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


Reply | Threaded
Open this post in threaded view
|

Re: Julian dates

David T. Lewis
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
>

Reply | Threaded
Open this post in threaded view
|

Re: Julian dates

Hannes Hirzel
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
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Julian dates

espin

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
>>
>
>



Reply | Threaded
Open this post in threaded view
|

Re: Julian dates

David T. Lewis
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
> > >>
> > >
> > >
> >
> >

>


Reply | Threaded
Open this post in threaded view
|

Re: Julian dates

espin

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:
GregorianDate julianDayNumber: 0
and obtain
24 November -4713 (GregorianDate)
instead of
1 January -4712 (JulianDate)

In my little Calendrica project I made that distinction explicit but the implicit convention of understanding Date being GregorianDate is equally valid.
It just needs a little bit more of text in the class comment.

HTH
Ciao

On Jun 26, 2012 10:39 PM, "David T. Lewis" <[hidden email]> wrote:
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
> > >>
> > >
> > >
> >
> >

>