Posts: 74
Threads: 13
Joined: Feb 2019
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
Posts: 325
Threads: 11
Joined: Feb 2010
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.
Posts: 74
Threads: 13
Joined: Feb 2019
Mar-03-2019, 10:06 AM
(This post was last modified: Mar-03-2019, 10:18 AM by samsonite.)
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
Posts: 7,315
Threads: 123
Joined: Sep 2016
Mar-03-2019, 11:47 AM
(This post was last modified: Mar-03-2019, 11:47 AM by snippsat.)
You are messing up your manual parsing
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
Posts: 325
Threads: 11
Joined: Feb 2010
(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).
Posts: 74
Threads: 13
Joined: Feb 2019
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)
Posts: 7,315
Threads: 123
Joined: Sep 2016
Mar-03-2019, 12:11 PM
(This post was last modified: Mar-03-2019, 12:12 PM by snippsat.)
(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
Posts: 74
Threads: 13
Joined: Feb 2019
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
Posts: 7,315
Threads: 123
Joined: Sep 2016
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.
Posts: 74
Threads: 13
Joined: Feb 2019
(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.
|