Python Forum

Full Version: Library (julian), lack of usage information
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Been installed julian from here: https://pypi.org/project/julian/ and got the related julian-0.14 package from Download files at lefside of the webpage, I realized that it works properly only when the back calculation julian.from_jd is carried out inside the same script of direct procedure julian.from_jd, as shown below:
# ------- jul1.py --------
import julian
import datetime
mjd = 58370.50847222222
dt = julian.from_jd(mjd, fmt='mjd')
print(dt)
#
jd = julian.to_jd(dt + datetime.timedelta(hours=12), fmt='jd')
print(jd-2400001)

# ------- OUTPUTS -----------
# 2018-09-09 12:12:12.000012
# 58370.50847222237
# My remark: mjd back calculation= jd-2400001
Nothing is said by the library author (lack of usage information) about calendar date string format in case the problem is formulated independentely: given date (2018-09-09) and time (12:12:12.0000), find mjd.

Here my trial code:
# ------- jul2.py --------
import julian
from datetime import datetime
#
#dt = '2007-09-29 18:43:11.999982'
#dt = datetime(year=2007, day=29, month=9)
#
jd = julian.to_jd(datetime(year=2007,month=9,day=29,hours=18,minutes=43,seconds=12.000), fmt='jd')
print(jd)
and error
Error:
C:\Training>python jul2.py Traceback (most recent call last): File "jul2.py", line 8, in <module> jd = julian.to_jd(datetime(year=2007,month=9,day=29,hours=18,minutes=43,seconds=12.000), fmt='jd') TypeError: 'hours' is an invalid keyword argument for this function
Before asking info to the author, I'ld like to get help from forum. Thanks in advance
I don't know anything about the library you're using, but the error you've shown is caused by passing wrong arguments to datetime.datetime().
hour, minute and second should all be singular.
I don't believe so, stranac! Same story with singulars hour=18,minute=43,second=12.000 as follows
Error:
C:\Training>python jul2.py Traceback (most recent call last): File "jul2.py", line 8, in <module> jd = julian.to_jd(datetime(year=2007,month=9,day=29,hour=18,minute=43,second=12.000), fmt='jd') TypeError: integer argument expected, got float
Thanks a lot, for your tentative. Cheers

More details, for helping me, can be taken from this source, coming from the julian package julian-0.14. That's the reason I mentioned the lack of information on thread title.
from datetime import datetime
import math


def __to_format(jd: float, fmt: str) -> float:
    """
    Converts a Julian Day object into a specific format.  For
    example, Modified Julian Day.
    Parameters
    ----------
    jd: float
    fmt: str

    Returns
    -------
    jd: float
    """
    if fmt.lower() == 'jd':
        return jd
    elif fmt.lower() == 'mjd':
        return jd - 2400000.5
    elif fmt.lower() == 'rjd':
        return jd - 2400000
    else:
        raise ValueError('Invalid Format')


def __from_format(jd: float, fmt: str) -> (int, float):
    """
    Converts a Julian Day format into the "standard" Julian
    day format.
    Parameters
    ----------
    jd
    fmt

    Returns
    -------
    (jd, fractional): (int, float)
         A tuple representing a Julian day.  The first number is the
         Julian Day Number, and the second is the fractional component of the
         day.  A fractional component of 0.5 represents noon.  Therefore
         the standard julian day would be (jd + fractional + 0.5)
    """
    if fmt.lower() == 'jd':
        # If jd has a fractional component of 0, then we are 12 hours into
        # the day
        return math.floor(jd + 0.5), jd + 0.5 - math.floor(jd + 0.5)
    elif fmt.lower() == 'mjd':
        return __from_format(jd + 2400000.5, 'jd')
    elif fmt.lower() == 'rjd':
        return __from_format(jd + 2400000, 'jd')
    else:
        raise ValueError('Invalid Format')


def to_jd(dt: datetime, fmt: str = 'jd') -> float:
    """
    Converts a given datetime object to Julian date.
    Algorithm is copied from https://en.wikipedia.org/wiki/Julian_day
    All variable names are consistent with the notation on the wiki page.

    Parameters
    ----------
    fmt
    dt: datetime
        Datetime object to convert to MJD

    Returns
    -------
    jd: float
    """
    a = math.floor((14-dt.month)/12)
    y = dt.year + 4800 - a
    m = dt.month + 12*a - 3

    jdn = dt.day + math.floor((153*m + 2)/5) + 365*y + math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045

    jd = jdn + (dt.hour - 12) / 24 + dt.minute / 1440 + dt.second / 86400 + dt.microsecond / 86400000000

    return __to_format(jd, fmt)


def from_jd(jd: float, fmt: str = 'jd') -> datetime:
    """
    Converts a Julian Date to a datetime object.
    Algorithm is from Fliegel and van Flandern (1968)

    Parameters
    ----------
    jd: float
        Julian Date as type specified in the string fmt

    fmt: str

    Returns
    -------
    dt: datetime

    """
    jd, jdf = __from_format(jd, fmt)

    l = jd+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
    k = l-2447*j//80
    l = j//11
    j = j+2-12*l
    i = 100*(n-49)+i+l

    year = int(i)
    month = int(j)
    day = int(k)

    # in microseconds
    frac_component = int(jdf * (1e6*24*3600))

    hours = int(frac_component // (1e6*3600))
    frac_component -= hours * 1e6*3600

    minutes = int(frac_component // (1e6*60))
    frac_component -= minutes * 1e6*60

    seconds = int(frac_component // 1e6)
    frac_component -= seconds*1e6

    frac_component = int(frac_component)

    dt = datetime(year=year, month=month, day=day,
                  hour=hours, minute=minutes, second=seconds, microsecond=frac_component)
    return dt
You are messing up your manual parsing Wink
First use strftime to get valid datetime object from the string.
>>> import datetime
>>> 
>>> dt = '2007-09-29 18:43:11.999982'
>>> my_date = datetime.datetime.strptime(dt, "%Y-%m-%d %H:%M:%S.%f")
>>> my_date
datetime.datetime(2007, 9, 29, 18, 43, 11, 999982)
>>> jd = julian.to_jd(my_date, fmt='jd')
>>> jd
2454373.28
Alternative dateutil which to can pare as string to datetime object.
>>> from dateutil.parser import parse
>>> 
>>> dt = '2007-09-29 18:43:11.999982'
>>> d = parse(dt)
>>> jd = julian.to_jd(d, fmt='jd')
>>> jd
2454373.28
Can also mention Pendulum,bye fair the best date library that has come out for Python the latest years.
>>> import pendulum
>>> 
>>> dt = '2007-09-29 18:43:11.999982'
>>> dt = pendulum.parse(dt)
# See also Timezone info
>>> dt
DateTime(2007, 9, 29, 18, 43, 11, 999982, tzinfo=Timezone('UTC'))
>>> jd = julian.to_jd(dt, fmt='jd')
>>> jd
2454373.28
(Mar-03-2019, 10:06 AM)samsonite Wrote: [ -> ]I don't believe so, stranac! Same story with singulars hour=18,minute=43,second=12.000 as follows
Error:
C:\Training>python jul2.py Traceback (most recent call last): File "jul2.py", line 8, in <module> jd = julian.to_jd(datetime(year=2007,month=9,day=29,hour=18,minute=43,second=12.000), fmt='jd') TypeError: integer argument expected, got float
That seems like a super-obvious error. 12.000 is a float, second has to be an int (12 would work).
Thank you, snippsat. But I'm expecting higher precision up to more decimals, according to this clue dt.second / 86400 + dt.microsecond / 86400000000 of the following function. Cheers
def to_jd(dt: datetime, fmt: str = 'jd') -> float:
    """
    Converts a given datetime object to Julian date.
    Algorithm is copied from https://en.wikipedia.org/wiki/Julian_day
    All variable names are consistent with the notation on the wiki page.
 
    Parameters
    ----------
    fmt
    dt: datetime
        Datetime object to convert to MJD
 
    Returns
    -------
    jd: float
    """
    a = math.floor((14-dt.month)/12)
    y = dt.year + 4800 - a
    m = dt.month + 12*a - 3
 
    jdn = dt.day + math.floor((153*m + 2)/5) + 365*y + math.floor(y/4) - math.floor(y/100) + math.floor(y/400) - 32045
 
    jd = jdn + (dt.hour - 12) / 24 + dt.minute / 1440 + dt.second / 86400 + dt.microsecond / 86400000000
 
    return __to_format(jd, fmt)
(Mar-03-2019, 11:59 AM)samsonite Wrote: [ -> ]Thank you, snippsat. But I'm expecting higher precision up to more decimals,
Then it's close to .28,try an other date.
>>> import julian
>>> import pendulum
>>> 
>>> dt = '2012-09-29 18:43:10.799982'
>>> dt = pendulum.parse(dt)
>>> julian.to_jd(dt, fmt='jd')
2456200.279986111
Here is what I'm expecting:
Output:
Given date and time as follows 2018-09-09 12:12:12.005876 (time accurate to 6 decimal places) find MJD 58370.50847229023
Cheers
Is this not okay?
>>> import julian
>>> import pendulum
>>> 
>>> dt = '2018-09-09 12:12:12.005876'
>>> dt = pendulum.parse(dt)
>>> dt
DateTime(2018, 9, 9, 12, 12, 12, 5876, tzinfo=Timezone('UTC'))
>>> julian.to_jd(dt, fmt='jd')
2458371.0084722904
Same or this is or more correct than Calendar date to Julian date which can take 1 decimal place in seconds.
(Mar-03-2019, 12:42 PM)snippsat Wrote: [ -> ]Is this not okay?
No, because of the unnecessary import pendulum. As a matter of completeness, I know that the web is full of scripts for solving the proposed problem, but my goal is to use only that library julian, which unfortunately has a crucial lack of usage information.
Nevertheless, thank you and the forum very much, sooner I'll ask news to the author.
Pages: 1 2