Sorry for the belated reply.  I've worked out a script, julian.r, that
converts dates to Julian Day Numbers, JD, for dates from 1-1-0001 to over
31-12-3000.  I've submitted it to www.rebol.org, but as they seem to be
somewhat slow, I'll include it herein. I'll also attach it. Sorry for the
length, but it's full of comments.  I tried to submit a script earlier in
November, but that one was limited to years 1901 through 2099, as it didn't
know that years divisible by 100 are not leap years unless they're divisible
by 400.  This current submission does and works from years 0001 through
3000.

It's epoch date is 1 Jan 4713 BC, as is common today in accounting.

REBOL
[ Title: {Julian Calendar Stuff}
date: 8-11-1999
file: %julian.r
author: {Russ Yost}
Email: [EMAIL PROTECTED]
Purpose: { To provide conversions to/from julian day numbers/dates }
Category: 'utility
Comment: {I'm not sure where these algorithms originated, but I used
        them in a JForth program in 1992.  The epoch date seems to be
        that set by Joseph Scaliger in 1582, i.e., Jan 1 4713 BC, (that
        would be Julian day number 1), but as this algorithm takes the
        average length of the solar year as 365.2425, it works over the
        range 0001 through 3000. Beyond then, the discrepancy with the
        true length, 365.242199, should lead to errors.
        (The year 2000, being divisible by 400,  will be a leap year,
although in general, years that are multiples of 100 are not
leap years. It *does* yield the correct Julian Day number given
in the 1999 World Almanac (World Almanac Books, Mahwah NJ) pg
322, for 31 Dec 1998, 2,451,179.)
        }

]
print {
    Two functions are defined herein, date-to-jul, with argument a
    date in format dd-mm-yyyy in  year range 0001 through 3000, and
    jul-to-date, with  argument a julian  day number (JD) based on 1 Jan
    4713 BC, with 31 Dec 1998's JD = 2451179 (as given in the 1999
    Almanac) and corresponding to the above mentioned range.
    This latter function also provides the day of the week for
    the given JD.

    Some other useful functions:
        diy, arg yyyy, yields the number of days in a given year.
        febdays, arg yyyy, yields the number of days in February.
        testj-d, arg yyyy, prints a  yyyy calendar, 1 line per month.
    }


jul0: 1720997 ; use with jul day based in 365.2425 days in year.

comment {There are 365.242199 solar days in a year, so the preceding
        assumption will lead to trouble after year 3000, I think.}

comment { 'jul0 also compensates for extra days added in the calculation
        of the number of days per month, and adjusts the result to agree
        with 1999 Almanac's statement that JD of 31 Dec 1998 is
        2,451,179.
        }

daysinyear: 365.2425
daysinmo: 30.6001 ; a synthesized number that is used to calc
                    ; days in each month.
weekdays: ["Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"]



idiv: func [x y][to-integer ( divide x y) ]

comment {REBOL ought to include an integer divide function! }


comment { Th func 'dye calcs a Julian day no based on 1-1-0001, taking
        into account years that are multiples of 4 are leap years
        (Feb has 29 days instead of 28) unless they're multiples of
        100 years, but those *are* leap years if they're multiples of
        400.
            }

comment {dye is day number of last day of year y }

dye: func[y][  (y * 365) + (((idiv y 4) - (idiv y 100)) + (idiv y 400))]


date-to-jul: func [date /local jul mo mox yr][
    jul:  date/day   + jul0
     yr: date/year
     mo: date/month
     either mo > 2 [mox: mo + 1  ] [
        mox: mo + 13 yr: yr - 1 ]
     jul: jul + (dye yr) + (to-integer mox * daysinmo)
]

jul-to-date: func [jl /local date da  mo yr dano][
    dano: jl - jul0
    dow: remainder (dano + 6) 7 ; Sunday = 0
    date: j2d jl
    da: date/day mo: date/month yr: date/year
    print [{date is  } to-date reduce[da mo yr]]
    print [{ day of week is }first skip weekdays dow]
]

j2d: func [ jl /local  dano yr mo da dow mox][
    dano: jl - jul0
    yr: to-integer ((dano - 122.1)  / daysinyear) ; print yr
    mox: to-integer((dano - (to-integer(yr * daysinyear))) / daysinmo)
    da: dano - (to-integer(yr * daysinyear))
    da: da -  (to-integer (mox * daysinmo))
    either mox < 14 [mo: mox - 1][ mo: mox - 13]
    if mo < 3 [yr: yr + 1]
    return to-date reduce [da mo yr]
]

comment { jdye is JD of last day of year }

jdye: func [y][ date-to-jul (to-date reduce [31 12 y])]

comment {'diy yields the number of days in a year - useful for checking
        leap years. }

diy: func [y][(jdye y )- (jdye (y - 1))]

febdays: func[y]
    [(date-to-jul (to-date reduce[1 3 y])) - date-to-jul (to-date
reduce[1 2 y])]

comment {'testj-d prints a calendar, 1 line per month for its argument,
         a year in format yyyy }

testj-d: func[yr /local strt-dt stjul dx da][
    strt-dt: to-date reduce [1 1 yr]
    stjul: date-to-jul strt-dt
    print {}
    for i 1 diy yr 1 [
        dx: j2d ( stjul + (i - 1))
        da: dx/day
        either da = 1 [
            prin [{^(line)} da {}]][
            prin [da {}]]
    ]
    print ""
]

******end of script ******

Russell [EMAIL PROTECTED]
----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Tuesday, November 02, 1999 2:07 PM
Subject: [REBOL] epoch? Re:(8)


> [snip - some algorithms]
>
> [EMAIL PROTECTED] wrote:
> >That appears to be a Julian day referenced to the start of the year.  My
> >understanding of a Julian day number is that it is the number of days
since
> >the start of the current Julian period, which started noon Jan 1 4713 BC.
>
> That's what a Julian date is in the real world :)
> As a computer term, a Julian date is any date calculated in the same
> manner as a real world Julian date, but possibly from a different base
> date. Whatever the base date is, that's called the epoch. The epoch
> for Unix is 1-Jan-1970, for DOS it's 1-Jan-1980. There are problems
> similar to Y2K when Julian date counters overflow or roll over.
>
> >Noon of Dec 31 1998 was the beginning of JD  2,451,179.  There is an
> >algorithm for calculating this number from a given date in the Gregorian
> >Calendar, our present calendar, but I don't have it at hand.  It requires
> >the use of a floor or ceiling function, the nearest integer smaller (or
> >greater) than a given decimal number.  The formula accounts for leap
years
> >and the days in each month.  It also starts a year on March 1, so
February
> >is the last month, and the formula truncates its length correctly.  I
> >implemented the formula in Forth using integers, but it was long ago -- .
>
> I don't know about anyone else here, but I'd be interested in seeing
> that algorithm if you could dig it up, even in Forth :)
>
> Brian
>

julian.r

Reply via email to