Welcome to the NavList Message Boards.

NavList:

A Community Devoted to the Preservation and Practice of Celestial Navigation and Other Methods of Traditional Wayfinding

Compose Your Message

Message:αβγ
Message:abc
Add Images & Files
    Name or NavList Code:
    Email:
       
    Reply
    Re: Julian Day Number algorithms
    From: Paul Hirose
    Date: 2024 Mar 20, 13:12 -0700

    There seems to be a rule that calendar algorithms are not allowed to use
    any obvious methods such as table lookup, branching, or iteration.
    Tradition requires clever hacks with minimum lines of code.
    
    Here I violate tradition with a Julian day number algorithm designed for
    easy understanding. It's valid for any BC or AD date in the Gregorian or
    Julian calendar. The time span is limited only by integer overflow.
    
    I begin with conversion from calendar date to GI (Gregorian integer),
    where GI 0 is the last day of year 0 (1 BC) in the Gregorian proleptic
    calendar. Days are numbered in sequence in both directions from that
    date: GI -1 is year 0 Dec 30 and GI +1 is year 1 Jan 1.
    
    In this algorithm the year number (y) uses the astronomical convention
    where 1 BC = 0, 2 BC = -1. etc. All divisions use integer math. For
    example, 2024 / 100 is exactly 20.
    
    1. If an AD year, decrement y. If BC, reverse the sign of y.
    
    2. Compute GI at the "0th" day of this year (last day of previous year).
    If the year is BC the formula gives a wrong result, but that's corrected
    in the next step. Remember, in integer division the remainder is discarded.
    
    GI = y * 365 + y / 4 - y / 100 + y / 400
    
    3. If BC, add 366 and negate.
    
    For example, in year 0 (1 BC), step 2 is zero. Adding 366 and reversing
    the sign gives -366, which is the correct GI at the 0th day of year 0
    (which has 366 days according to the leap year rules).
    
    In similar fashion we can validate the result in year -1 (2 BC): step 2
    is 365, corrected to -731 in step 3. That's the GI at the 0th day of
    year -1.
    
    4. At this point we have the GI at the 0th year of the year. Now add the
    days in the whole months. E.g., for a March date add 31 and 28 (or 29 if
    a leap year).
    
    5. At this point we have the GI at the 0th day of this month. Add day of
    month.
    
    For example, calculate GI at 2024 March 19. Per step 1, adjust y to
    2023. Step 2 is GI = 2023 * 365 + 2023 / 4 - 2023 / 100 + 2023 / 400 =
    738 885. Step 3 does not apply since the date is AD. Step 4 adds 31 and
    29. In step 5 add 19 to get 738 964 for the GI.
    
    For dates in the Julian calendar a Julian integer can be calculated with
    a similar method. In step 2 use the formula JI = y * 365 + y / 4. In
    step 4 use Julian rules to determine the number of days in February.
    
    For example, calculate JI at 2024 March 6 (equivalent to the Gregorian
    calendar date just calculated). Step 2 is JI = 2023 * 365 + 2023 / 4 =
    738 900. Add 31 and 29 for January and February. Add 6 for day of month.
    JI = 738 966, or 2 more than GI on the same day.
    
    Since GI and JI proceed in parallel into the past and future, JI is
    always GI + 2. GI and JI also have constant differences from JDN (Julian
    day number).
    
    To determine the differences, calculate JI at the JDN zero point: -4712
    Jan 1, Julian calendar. Per step 1, change -4712 to +4712. Step 2 is JI
    = 4712 * 365 + 4712 / 4 = 1 721 058. Per step 3, add 366 and negate.
    Result is -1 721 424. Step 4 is not applicable since there are no whole
    months before a January date. In step 5 add 1 for day of month to get JI
    -1 721 423.
    
    Thus, JDN 0 = JI -1 721 423. And since GI is always 2 less than JI, we
    can also say that JDN 0 = GI -1 721 425. Or to put it another way, JDN =
    GI + 1 721 425. To verify, convert the previously calculated GI (738 964
    at 2024 March 19) to JDN. Result is JDN 2 460 389. That agrees with the
    table in Almanac section K:
    
    https://archive.org/details/binder1_202003/page/n539/mode/1up?view=theater
    
    In a computer implementation I use a 2-dimensional array in step 4:
    {{31, 28, 31...}, {31, 29, 31...}} and iterate to add the days in the
    whole months. (With the same array you can verify day of month does not
    exceed the legal range.) To select the correct row I wrote function
    IsLeapYear(y, julian). The "julian" parameter is true for Julian
    calendar dates. The function returns 0 if y is a normal year or 1 if
    leap. That value indexes into the correct row of the array. (The year
    passed to the function must be the actual value, before it's modified in
    step 1.)
    
    I'll explain the reverse conversion (JDN to calendar date) in a followup.
    
    --
    Paul Hirose
    sofajpl.com
    
    

       
    Reply
    Browse Files

    Drop Files

    NavList

    What is NavList?

    Get a NavList ID Code

    Name:
    (please, no nicknames or handles)
    Email:
    Do you want to receive all group messages by email?
    Yes No

    A NavList ID Code guarantees your identity in NavList posts and allows faster posting of messages.

    Retrieve a NavList ID Code

    Enter the email address associated with your NavList messages. Your NavList code will be emailed to you immediately.
    Email:

    Email Settings

    NavList ID Code:

    Custom Index

    Subject:
    Author:
    Start date: (yyyymm dd)
    End date: (yyyymm dd)

    Visit this site
    Visit this site
    Visit this site
    Visit this site
    Visit this site
    Visit this site