Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.forth > #56294 > unrolled thread

Dates in Forth

Started byCharles Montgomery <cgm@physics.utoledo.edu>
First post2017-03-25 16:36 -0400
Last post2017-03-29 10:39 -0700
Articles 8 — 7 participants

Back to article view | Back to comp.lang.forth


Contents

  Dates in Forth Charles Montgomery <cgm@physics.utoledo.edu> - 2017-03-25 16:36 -0400
    Re: Dates in Forth Alex <alex@rivadpm.com> - 2017-03-25 20:45 +0000
    Re: Dates in Forth "Elizabeth D. Rather" <erather@forth.com> - 2017-03-25 11:34 -1000
    Re: Dates in Forth krishna.myneni@ccreweb.org - 2017-03-25 18:31 -0700
      Re: Dates in Forth Ron Aaron <rambamist@gmail.com> - 2017-03-26 06:57 +0300
        Re: Dates in Forth krishna.myneni@ccreweb.org - 2017-03-26 05:15 -0700
    Re: Dates in Forth Mark Wills <markwills1970@gmail.com> - 2017-03-26 02:29 -0700
    Dates in Forth lehs <skydda.barnen@gmail.com> - 2017-03-29 10:39 -0700

#56294 — Dates in Forth

FromCharles Montgomery <cgm@physics.utoledo.edu>
Date2017-03-25 16:36 -0400
SubjectDates in Forth
Message-ID<ob6k7q$747$1@dont-email.me>
The fundamental item for treating dates in Forth is Will Baden's
word to calculate the Julian Day for a date in the Gregorian calendar.

( The Julian Day is the number of days since 1 January 4713 BC.)
: JD                ( dd mm yyyy -- julian-day )
    >R                            ( dd mm)( R: yyyy)
        3 -  DUP 0< IF  12 +  R> 1- >R  THEN
        306 *  5 +  10 /  +       ( day)
        R@  1461 4 */  +  1721116 +
           DUP 2299169 > IF
               3 +  R@ 100 / -  R@ 400 / +
           THEN
    R> DROP                               ( R: )
;

The day of the week is just the Julian Day mod 7.

For many purposes the Julian Fay is replaced by the 
Modified Julian Day, which is just the Julian Day minus 2400000.5.
Its primary advantage is that the values aren't so huge and require
less storage space.  It is zero for November 17. 1878.
The half day is present because the Julian Day goes from one noon
to the next, while the Modified Julian Day goes from midnight to midnight 
like civil time.  Time on the Greenwich meridian, of course.

It should be noted that the Gregorian calendar was adopted in different 
ways at different times in different parts of the world.  This causes no
problems for positive Modified Julian Days, though it limits the range of
applicability of Zeller's Congruence, for example.

: MJD      ( dd mm yyyy - mod-julian-day )
    >R  3 - DUP 0< IF  12 + R> 1- >R  THEN
    153 * 2 + 5 /  +       ( day  R:year )
    R@  1461 4 */  +  678882 -  R@ 100 / -  R> 400 / +
;

A more interesting task, for which I have been unable to find a 
published Forth solution, is the inverse problem: given the JD or MJD.
compute the day, month, and year in the Gregorian calendar.
I have a solution which works, but that I am not happy with.  Does it 
really have to be this complicated, or is there some number-theory tidbit 
that I am failing to recognize?

: DJM4  (  Modified Julian Day -- year month day  )
    51604 - 146097 /mod swap
    dup 146096 = IF drop 3 36524 ELSE 36524 /mod swap THEN
    1461 /mod swap  DUP 1460 = IF drop 3 366 ELSE 365 /mod swap 1+ THEN
    >R  rot 100 * + rot 400 * + swap 4 * + 2000 +  R>
    5 * 3 - 153 /mod swap 5 / 1+
    >R  3 + DUP  >R  12 >  IF 1 + R> 12 - ELSE R> THEN  R>  ;
    
I hesitate to take up space on comp.lang.forth with a version with stack 
comments and an explanation of what on earth is going on, because it may 
Not be Of General Interest.  I'd be happy to provide more details by email 
if anyone is interested.  Or to post more if there is interest.

regards to all   cgm

[toc] | [next] | [standalone]


#56295

FromAlex <alex@rivadpm.com>
Date2017-03-25 20:45 +0000
Message-ID<ob6ko7$8ob$1@dont-email.me>
In reply to#56294
On 3/25/2017 20:36, Charles Montgomery wrote:
> Or to post more if there is interest.

Please. It's the best post on the subject by a country mile.

-- 
Alex

[toc] | [prev] | [next] | [standalone]


#56297

From"Elizabeth D. Rather" <erather@forth.com>
Date2017-03-25 11:34 -1000
Message-ID<6bKdnd165-_zf0vFnZ2dnUU7-IPNnZ2d@supernews.com>
In reply to#56294
On 3/25/17 10:36 AM, Charles Montgomery wrote:
> The fundamental item for treating dates in Forth is Will Baden's
> word to calculate the Julian Day for a date in the Gregorian calendar.
>
> ( The Julian Day is the number of days since 1 January 4713 BC.)
> : JD                ( dd mm yyyy -- julian-day )
>     >R                            ( dd mm)( R: yyyy)
>         3 -  DUP 0< IF  12 +  R> 1- >R  THEN
>         306 *  5 +  10 /  +       ( day)
>         R@  1461 4 */  +  1721116 +
>            DUP 2299169 > IF
>                3 +  R@ 100 / -  R@ 400 / +
>            THEN
>     R> DROP                               ( R: )
> ;
>
> The day of the week is just the Julian Day mod 7.
>
> For many purposes the Julian Fay is replaced by the
> Modified Julian Day, which is just the Julian Day minus 2400000.5.
> Its primary advantage is that the values aren't so huge and require
> less storage space.  It is zero for November 17. 1878.
> The half day is present because the Julian Day goes from one noon
> to the next, while the Modified Julian Day goes from midnight to midnight
> like civil time.  Time on the Greenwich meridian, of course.
>
> It should be noted that the Gregorian calendar was adopted in different
> ways at different times in different parts of the world.  This causes no
> problems for positive Modified Julian Days, though it limits the range of
> applicability of Zeller's Congruence, for example.
>
> : MJD      ( dd mm yyyy - mod-julian-day )
>     >R  3 - DUP 0< IF  12 + R> 1- >R  THEN
>     153 * 2 + 5 /  +       ( day  R:year )
>     R@  1461 4 */  +  678882 -  R@ 100 / -  R> 400 / +
> ;
>
> A more interesting task, for which I have been unable to find a
> published Forth solution, is the inverse problem: given the JD or MJD.
> compute the day, month, and year in the Gregorian calendar.
> I have a solution which works, but that I am not happy with.  Does it
> really have to be this complicated, or is there some number-theory tidbit
> that I am failing to recognize?
>
> : DJM4  (  Modified Julian Day -- year month day  )
>     51604 - 146097 /mod swap
>     dup 146096 = IF drop 3 36524 ELSE 36524 /mod swap THEN
>     1461 /mod swap  DUP 1460 = IF drop 3 366 ELSE 365 /mod swap 1+ THEN
>     >R  rot 100 * + rot 400 * + swap 4 * + 2000 +  R>
>     5 * 3 - 153 /mod swap 5 / 1+
>     >R  3 + DUP  >R  12 >  IF 1 + R> 12 - ELSE R> THEN  R>  ;
>
> I hesitate to take up space on comp.lang.forth with a version with stack
> comments and an explanation of what on earth is going on, because it may
> Not be Of General Interest.  I'd be happy to provide more details by email
> if anyone is interested.  Or to post more if there is interest.

Chuck based his earliest calendars at NRAO on this concept, and this 
method has been used by FORTH, Inc. ever since, although we factor it 
somewhat differently from the examples above. Dates are always kept as 
MJD internally, and translated to the output format of choice for 
display. It makes it really easy to do arithmetic on dates, as well as 
making them smaller. Yeah, yeah, I know it's unfashionable to worry 
about "small" nowadays, but when you have a database of millions of 
records, as we sometimes do, it's useful to save a bunch of bytes for 
something that may be in every record.

Cheers,
Elizabeth


-- 
Elizabeth R. Conklin
FORTH, Inc.
6080 Center Drive, Suite 600
Los Angeles, CA  90045
USA

[toc] | [prev] | [next] | [standalone]


#56308

Fromkrishna.myneni@ccreweb.org
Date2017-03-25 18:31 -0700
Message-ID<67b79ab1-50bf-408b-8386-8d97bb709535@googlegroups.com>
In reply to#56294
On Saturday, March 25, 2017 at 3:37:00 PM UTC-5, Charles Montgomery wrote:
...
> A more interesting task, for which I have been unable to find a 
> published Forth solution, is the inverse problem: given the JD or MJD.
> compute the day, month, and year in the Gregorian calendar.
> I have a solution which works, but that I am not happy with.  Does it 
> really have to be this complicated, or is there some number-theory tidbit 
> that I am failing to recognize?
> 
> : DJM4  (  Modified Julian Day -- year month day  )
>     51604 - 146097 /mod swap
>     dup 146096 = IF drop 3 36524 ELSE 36524 /mod swap THEN
>     1461 /mod swap  DUP 1460 = IF drop 3 366 ELSE 365 /mod swap 1+ THEN
>     >R  rot 100 * + rot 400 * + swap 4 * + 2000 +  R>
>     5 * 3 - 153 /mod swap 5 / 1+
>     >R  3 + DUP  >R  12 >  IF 1 + R> 12 - ELSE R> THEN  R>  ;
>     
> I hesitate to take up space on comp.lang.forth with a version with stack 
> comments and an explanation of what on earth is going on, because it may 
> Not be Of General Interest.  I'd be happy to provide more details by email 
> if anyone is interested.  Or to post more if there is interest.
...

Yes, please. This will be a nice addition to a generic Forth toolbox. An explanation of what the code is doing would be appreciated.

Krishna

[toc] | [prev] | [next] | [standalone]


#56314

FromRon Aaron <rambamist@gmail.com>
Date2017-03-26 06:57 +0300
Message-ID<ob7e1p$5b6$1@dont-email.me>
In reply to#56308

On 26/03/2017 4:31, krishna.myneni@ccreweb.org wrote:
> On Saturday, March 25, 2017 at 3:37:00 PM UTC-5, Charles Montgomery wrote:
> ...
>> A more interesting task, for which I have been unable to find a 
>> published Forth solution, is the inverse problem: given the JD or MJD.
>> compute the day, month, and year in the Gregorian calendar.
>> I have a solution which works, but that I am not happy with.  Does it 
>> really have to be this complicated, or is there some number-theory tidbit 
>> that I am failing to recognize?
>>
>> : DJM4  (  Modified Julian Day -- year month day  )
>>     51604 - 146097 /mod swap
>>     dup 146096 = IF drop 3 36524 ELSE 36524 /mod swap THEN
>>     1461 /mod swap  DUP 1460 = IF drop 3 366 ELSE 365 /mod swap 1+ THEN
>>     >R  rot 100 * + rot 400 * + swap 4 * + 2000 +  R>
>>     5 * 3 - 153 /mod swap 5 / 1+
>>     >R  3 + DUP  >R  12 >  IF 1 + R> 12 - ELSE R> THEN  R>  ;
>>     
>> I hesitate to take up space on comp.lang.forth with a version with stack 
>> comments and an explanation of what on earth is going on, because it may 
>> Not be Of General Interest.  I'd be happy to provide more details by email 
>> if anyone is interested.  Or to post more if there is interest.
> ...
> 
> Yes, please. This will be a nice addition to a generic Forth toolbox. An explanation of what the code is doing would be appreciated.
> 
> Krishna

Wil Baden's toolbox has a version of this.  It's based on the code in
the "Calendrica" suite:
https://www.cs.tau.ac.il/~nachum/calendar-book/index.shtml

The "Calendrical Calculations" books are fascinating, IMO.  Well worth
reading if you're interested in calendar mathematics.

[toc] | [prev] | [next] | [standalone]


#56338

Fromkrishna.myneni@ccreweb.org
Date2017-03-26 05:15 -0700
Message-ID<41a452cb-180a-4b07-a199-89fdf391abbd@googlegroups.com>
In reply to#56314
On Saturday, March 25, 2017 at 10:57:31 PM UTC-5, Ron Aaron wrote:
> On 26/03/2017 4:31, krishna.myneni@ccreweb.org wrote:
> > On Saturday, March 25, 2017 at 3:37:00 PM UTC-5, Charles Montgomery wrote:
> > ...
> >> A more interesting task, for which I have been unable to find a 
> >> published Forth solution, is the inverse problem: given the JD or MJD.
> >> compute the day, month, and year in the Gregorian calendar.
> >> I have a solution which works, but that I am not happy with.  Does it 
> >> really have to be this complicated, or is there some number-theory tidbit 
> >> that I am failing to recognize?
> >>
> >> : DJM4  (  Modified Julian Day -- year month day  )
> >>     51604 - 146097 /mod swap
> >>     dup 146096 = IF drop 3 36524 ELSE 36524 /mod swap THEN
> >>     1461 /mod swap  DUP 1460 = IF drop 3 366 ELSE 365 /mod swap 1+ THEN
> >>     >R  rot 100 * + rot 400 * + swap 4 * + 2000 +  R>
> >>     5 * 3 - 153 /mod swap 5 / 1+
> >>     >R  3 + DUP  >R  12 >  IF 1 + R> 12 - ELSE R> THEN  R>  ;
> >>     
> >> I hesitate to take up space on comp.lang.forth with a version with stack 
> >> comments and an explanation of what on earth is going on, because it may 
> >> Not be Of General Interest.  I'd be happy to provide more details by email 
> >> if anyone is interested.  Or to post more if there is interest.
> > ...
> > 
> > Yes, please. This will be a nice addition to a generic Forth toolbox. An explanation of what the code is doing would be appreciated.
> > 
> > Krishna
> 
> Wil Baden's toolbox has a version of this.  It's based on the code in
> the "Calendrica" suite:
> https://www.cs.tau.ac.il/~nachum/calendar-book/index.shtml
> 
> The "Calendrical Calculations" books are fascinating, IMO.  Well worth
> reading if you're interested in calendar mathematics.

Thanks, Ron. I used Wil Baden's JD and calendar code in my set of Forth utilities -- I believe he posted them on c.l.f. a long time ago. But, I didn't have the inversion code to turn a JD back into date.

Krishna

[toc] | [prev] | [next] | [standalone]


#56333

FromMark Wills <markwills1970@gmail.com>
Date2017-03-26 02:29 -0700
Message-ID<943bad96-5252-41fb-aafe-aa66f11bdbaa@googlegroups.com>
In reply to#56294
There's a nice page here with code to compute a day number from a date,
and back again:

https://alcor.concordia.ca//~gpkatch/gdate-algorithm.html

C implementation also given, plus a nice explanation of the math.




On Saturday, 25 March 2017 20:37:00 UTC, Charles Montgomery  wrote:
> The fundamental item for treating dates in Forth is Will Baden's
> word to calculate the Julian Day for a date in the Gregorian calendar.
> 
> ( The Julian Day is the number of days since 1 January 4713 BC.)
> : JD                ( dd mm yyyy -- julian-day )
>     >R                            ( dd mm)( R: yyyy)
>         3 -  DUP 0< IF  12 +  R> 1- >R  THEN
>         306 *  5 +  10 /  +       ( day)
>         R@  1461 4 */  +  1721116 +
>            DUP 2299169 > IF
>                3 +  R@ 100 / -  R@ 400 / +
>            THEN
>     R> DROP                               ( R: )
> ;
> 
> The day of the week is just the Julian Day mod 7.
> 
> For many purposes the Julian Fay is replaced by the 
> Modified Julian Day, which is just the Julian Day minus 2400000.5.
> Its primary advantage is that the values aren't so huge and require
> less storage space.  It is zero for November 17. 1878.
> The half day is present because the Julian Day goes from one noon
> to the next, while the Modified Julian Day goes from midnight to midnight 
> like civil time.  Time on the Greenwich meridian, of course.
> 
> It should be noted that the Gregorian calendar was adopted in different 
> ways at different times in different parts of the world.  This causes no
> problems for positive Modified Julian Days, though it limits the range of
> applicability of Zeller's Congruence, for example.
> 
> : MJD      ( dd mm yyyy - mod-julian-day )
>     >R  3 - DUP 0< IF  12 + R> 1- >R  THEN
>     153 * 2 + 5 /  +       ( day  R:year )
>     R@  1461 4 */  +  678882 -  R@ 100 / -  R> 400 / +
> ;
> 
> A more interesting task, for which I have been unable to find a 
> published Forth solution, is the inverse problem: given the JD or MJD.
> compute the day, month, and year in the Gregorian calendar.
> I have a solution which works, but that I am not happy with.  Does it 
> really have to be this complicated, or is there some number-theory tidbit 
> that I am failing to recognize?
> 
> : DJM4  (  Modified Julian Day -- year month day  )
>     51604 - 146097 /mod swap
>     dup 146096 = IF drop 3 36524 ELSE 36524 /mod swap THEN
>     1461 /mod swap  DUP 1460 = IF drop 3 366 ELSE 365 /mod swap 1+ THEN
>     >R  rot 100 * + rot 400 * + swap 4 * + 2000 +  R>
>     5 * 3 - 153 /mod swap 5 / 1+
>     >R  3 + DUP  >R  12 >  IF 1 + R> 12 - ELSE R> THEN  R>  ;
>     
> I hesitate to take up space on comp.lang.forth with a version with stack 
> comments and an explanation of what on earth is going on, because it may 
> Not be Of General Interest.  I'd be happy to provide more details by email 
> if anyone is interested.  Or to post more if there is interest.
> 
> regards to all   cgm

[toc] | [prev] | [next] | [standalone]


#56461

Fromlehs <skydda.barnen@gmail.com>
Date2017-03-29 10:39 -0700
Message-ID<d4fb2a40-20c0-48b7-8c83-b6fa9f47d27b@googlegroups.com>
In reply to#56294
What about week number and eastern? Due to Wikipedia there are three systems for week numbering and I have tried to code the system used in Europe.

https://en.wikipedia.org/wiki/Week#Week_numbering

: doy  \ y m d -- n
  2 pick >r
  mjd r> 1 1 mjd - 1+ ;

: week-eu  \ y m d -- n
  2 pick 1 4 mjd dow ?dup   \ y m d dow dow?
  if negate 12 +  \ y m d 12-dow
  else 5  \ y m d 5
  then >r  \ first day of week 2 in r
  doy r> - dup 0<  \ doy-r flag
  if 7 + 0< 
     if 52 else 1 then
  else 7 / 2 + 
  then ; 

https://forthmath.blogspot.se

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.forth


csiph-web