Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Julian Day
#1
Here is another Python piece of code derived from Jean Meuus' book "Astronomical Algorithms"
to compute the Julian Day (JD) for a given Gregorian date and time. This formula uses the
astronomical definition of JD in that it includes the year '0', whereas the historical
definition does not. If you enter a decimal day, you will not receive any more prompts, otherwise
you will be prompted for the hours (in military time), minutes and seconds UT. Comments and improvements
are appreciated, but NOT to the function "def gtoj"

from calendar import monthrange


###################################################################################################
# Convert a Gregorian Date to a Julian Day using Jean Meeus formula 7.1
###################################################################################################

def g2j(year, month, day):
    if month == 1 or month == 2:
        year -= 1
        month += 12
    if month > 2:
        year = year
        month = month
    if year >= 1582:
        a = int(year / 100)
        b = 2 - a + int(a / 4)
    else:
        b = 0

    jd = int(365.25 * (year + 4716)) + int(30.6001 * (month + 1)) + day + b - 1524.5
    return jd

###################################################################################################
# Convert day to decimal day
###################################################################################################


def day2decday(d_day, d_hour, d_min, d_sec):
    if d_hour >= 0:
        d_day = d_day + d_hour/24 + d_min/(24 * 60) + d_sec/(24 * 3600)
    return d_day

my_year = 0
my_month = 0
my_day = 0.0

while True:
    try:
        my_year = int(input('Please enter the 4 digit year (-4712 to 2100): '))
        if -4712 <= my_year <= 2100:    # Historical Julian date starts -4713 (no year 0 (zero)
            break
        else:
            print('\n WARNING: Year out of range, must be a whole number between -4712 and 2100 ')
    except ValueError:
        print('\n ERROR: Year must be numeric and a whole number between -4712 and 2100 ')

while True:
    try:
        my_month = int(input('Please enter the digit month (1 - 12): '))
        if 1 <= my_month <= 12:
            break
        else:
            print('\n WARNING: Month out of range, must be a whole number between 1 and 12 ')
    except ValueError:
        print('\n ERROR: Month must be numeric and a whole number between 1 and 12 ')

days_in_month = monthrange(my_year, my_month)

while True:
    try:
        my_day = float(input('Please enter the day: '))
        if 1.0 <= my_day <= days_in_month[1]:
            break
        else:
            print('\n WARNING: Day out of range, must be a number between 1 and {} '
                  .format(days_in_month[1]))
    except ValueError:
        print('\n ERROR: Day out of range, must be a number between 1 and {} '
              .format(days_in_month[1]))

if my_day > int(my_day):
    my_day = my_day
    greg2jul = g2j(my_year, my_month, my_day)
else:
    print('\nEnter Greenwich UTC time')
    my_hour = int(input('Enter the hour (24 hour clock): '))
    my_min = int(input('Enter the number minutes: '))
    my_sec = int(input('Enter the number of seconds: '))

    dec_day = day2decday(my_day, my_hour, my_min, my_sec)
    greg2jul = g2j(my_year, my_month, dec_day)

print('\nJulian Day: ', str(greg2jul))

# 1957 October 4.81 should = 2436116.31
# 333 January 27 at 1200 hrs UT = 1842713.0
#
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
#2
Nicely done sparkz_alot! Have you tested the functions against some already calculated transforms to make checks?
#3
(Oct-06-2016, 06:15 PM)j.crater Wrote: Nicely done sparkz_alot! Have you tested the functions against some already calculated transforms to make checks?

darn you, j.crater :naughty: , thought I covered it all. Then after reading your post, thought maybe I'd better check some more. Sure enough ran into a problem with negative years. It appears Pythons calendar.monthrange only covers the positive years 1-9999, causing:
Error:
Please enter the 4 digit year (-4712 to 2100): -1000 Please enter the digit month (1 - 12): 7 Traceback (most recent call last):   File "C:/Python/Astronomy/meeus/scratch.py", line 60, in <module>     days_in_month = monthrange(my_year, my_month)   File "C:\Python 3.5\lib\calendar.py", line 121, in monthrange     day1 = weekday(year, month, 1)   File "C:\Python 3.5\lib\calendar.py", line 113, in weekday     return datetime.date(year, month, day).weekday() ValueError: year is out of range Process finished with exit code 1
Looks like I'll have to replace the calendar library with some other way to test the "day". Thanks for the catch  :D
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
#4
Hehe, I didn't catch anything, I was just curious whether you have tested the functions :D
So nice find there, and just in time, I am sure you will solve it easily =)
#5
BTDT in C.  i think datetime can do this (and with some added code also reverse it).

edit:

it probably has a more limit year range.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
#6
(Oct-07-2016, 04:17 AM)Skaperen Wrote: BTDT in C.  i think datetime can do this (and with some added code also reverse it).

edit:

it probably has a more limit year range.

Actually, calendar uses datetime.  The only reason it's there is as a test of user input to ensure they input a correct 'day' for that particular month, for instance, putting in day 45 for the month of january.  To Mr Meuus' credit, if you remove all the 'tests' and just use the 'def g2j:' function, it works perfect; for negative years, positive years, whole days and decimal days. I added the tests because...well, I don't trust people  :) other than that, calendar really serves no other purpose.
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
#7
what about putting in day 31 for September?

BTW, my C code was core arithmetic, not user interface checking.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
#8
Quote:what about putting in day 31 for September?

sorry, not sure what you mean. If you enter year, 9 , 31 you will get

Please enter the 4 digit year (-4712 to 2100): 1951
Please enter the digit month (1 - 12): 9
Please enter the day: 31
Error:
 WARNING: Day out of range, must be a number between 1 and 30  Please enter the day:
I'm thinking the simple solution would be to take the absolute value of year, then its a matter of ignoring leap years for that time period. I'll have to give it a try over the weekend, perhaps.
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
#9
(Oct-08-2016, 01:41 AM)sparkz_alot Wrote: I'm thinking the simple solution would be to take the absolute value of year, then its a matter of ignoring leap years for that time period. I'll have to give it a try over the weekend, perhaps.

don't forget that 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12 and 9 BC are leap years and 4 BC, 0, and 4 AD are not. then leap years are every 4 years until whatever year the transition from Julian to Gregorian was adopted where you are.  are you doing proleptic Gregorian?

what if i entered 1752 for the year, and 9 for September, and a date of 3.  would it reject that date?

i worked out another system that is even more accurate and also simpler, but they would never adopt it.  for it to work, it would have to be adopted before 2028.

now how can someone use this code in their GUI programs?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
#10
(Oct-08-2016, 04:11 AM)Skaperen Wrote:
(Oct-08-2016, 01:41 AM)sparkz_alot Wrote: I'm thinking the simple solution would be to take the absolute value of year, then its a matter of ignoring leap years for that time period. I'll have to give it a try over the weekend, perhaps.

don't forget that 45, 42, 39, 36, 33, 30, 27, 24, 21, 18, 15, 12 and 9 BC are leap years and 4 BC, 0, and 4 AD are not. then leap years are every 4 years until whatever year the transition from Julian to Gregorian was adopted where you are.  are you doing proleptic Gregorian?

what if i entered 1752 for the year, and 9 for September, and a date of 3.  would it reject that date?

i worked out another system that is even more accurate and also simpler, but they would never adopt it.  for it to work, it would have to be adopted before 2028.

now how can someone use this code in their GUI programs?

If you input the date, 1752-9-3 at 1200 hrs, you get a JD of 2361211.0, which jives with US Naval Observatory. As to the years prior to 1752 (though there appears to be some debate on this year) at least from year 8 AD a leap year was every 4 years...period. 
again though, this snag only applies to testing the user input, the formula itself (if given the correct information) is quite accurate.

Quote:i worked out another system that is even more accurate and also simpler, but they would never adopt it.  for it to work, it would have to be adopted before 2028.
 It would be interesting to see.  And you never know, the international committee has been known to adapt  :D

Quote:now how can someone use this code in their GUI programs?

Probably so, but not by me  :D  .
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020