irfpy.util.julday

Implementation of Julian day.

Code author: Yoshifumi Futaana

This irfpy.util.julday package provides implementation of Julian day and related functionality.

It consists of mainly three classes:

Some helper functions can bridge the Julday object and datetime.datetime object.

Note

Currently JdObject and JdSeries are not used frequently. Similar functionalities are found at irfpy.util.timeseries.ScalarSeries or irfpy.util.timeseries.Vector3dSeries These are limited to the floating point values, but much faster and intuitive. Prioritize to use irfpy.util.timeseries functionality.

Note

It is recommended to use datetime.datetime for nominal use. Using irfpy.util.julday.Julday is not very recommended; only for converting to datetime.datetime. See also irfpy.util.utc.

class irfpy.util.julday.Julday(yr_or_jd, mo=None, dy=None, hr=None, mn=None, se=None)[source]

Bases: object

Julian day class.

Parameters:

yr_or_jd – Float, Julday or datetime.datetime instance specifying the time.

>>> from irfpy.util.julday import Julday
>>> jd = Julday(2008, 11, 10, 13, 51, 25.371)
>>> print(jd)   
2454781.07738(2008-11-10T13:51:25.371)
>>> jd2 = Julday(jd)
>>> print(jd2)
 2454781.07738(2008-11-10T13:51:25.371)
>>> dt = jd.getDatetime()
>>> print(dt)  # Note: double precision!!
2008-11-10 13:51:25.370980
>>> jd3 = Julday(dt)
>>> print(jd3)   
2454781.07738(2008-11-10T13:51:25.371)

Deprecateed method: Previously , one can get julday in double format by jd.jd However, this call is not supported anymore. Use juld().

>>> jd = Julday(1, 1, 1, 0, 0, 0)   #  corresponding to 1721423.5
>>> print('%.5f' % jd.juld())
1721423.50000
>>> jd = Julday(2000000.5)   # JD=2000000.5 is 0763-09-15 0:0:0
>>> print(jd.to_string())
0763-09-15T00:00:00.000

Todo

It is planned to implement comparison with a natural python way.

Instance the Julday object.

HOUR = 0.041666666666666664
MINUTE = 0.0006944444444444444
SECOND = 1.1574074074074073e-05
juld()[source]

Return double precision expression of julian day.

classmethod cal2jd(year, month, day, hour, minute, second)[source]

A class method to calculate the julian day.

classmethod jd2cal(jd)[source]

A class method to return a tuple of calendar.

getDatetime()[source]

Return the corresponding time in datetime.datetime format.

dayFrom(julday)[source]

Return the difference in time, i.e. self.juld() - julday.juld().

>>> jd0 = Julday(2009, 1, 10, 12, 0, 0)
>>> jd1 = Julday(2009, 1, 12, 6, 0, 0)
>>> print(jd0.dayFrom(jd1))
-1.75
dayAfter(days)[source]

Return the Julday instance after the specified day.

>>> jd0 = Julday(2010, 5, 3, 0, 0, 0)
>>> jd1 = jd0.dayAfter(31.5)
>>> print(jd1.getDatetime())
2010-06-03 12:00:00
isEarlier(julday)[source]

Return True if the self is earlier than the specified julday

>>> jd0 = Julday(2005, 1, 1, 0, 0, 0)
>>> jd1 = Julday(2006, 1, 1, 0, 0, 0)
>>> print(jd0.isEarlier(jd1))
True
>>> print(jd0.isEarlier(jd0))
False
>>> print(jd1.isEarlier(jd0))
False
isLater(julday)[source]

Return True if the self is later than the specified julday

>>> jd0 = Julday(2005, 1, 1, 0, 0, 0)
>>> jd1 = Julday(2006, 1, 1, 0, 0, 0)
>>> print(jd0.isLater(jd1))
False
>>> print(jd0.isLater(jd0))
False
>>> print(jd1.isLater(jd0))
True
isSame(julday)[source]

Return True if both the time is the same.

Comparison by values, not object.

>>> jd0 = Julday(2009, 1, 10, 12, 0, 0)
>>> jd1 = Julday(2012, 1, 10, 12, 0, 0)
>>> jd2 = Julday(2009, 1, 10, 12, 0, 0)
>>> jd3 = jd0
>>> print(jd0.isSame(jd0))
True
>>> print(jd0.isSame(jd1))
False
>>> print(jd0.isSame(jd2))
True
>>> print(jd0.isSame(jd3))
True
>>> print(jd0 is jd2)
False
>>> print(jd0 is jd3)
True
to_string()[source]
getTimedelta(other)[source]

Return datetime.timedelta object for self-other

class irfpy.util.julday.JdObject(julday, object)[source]

Bases: object

A pair of julian day and any object.

The object is NOT deep-copied. It is stored by reference (just by ‘=’). Therefore, if you changed the object after making the JdObject instance, the contents inside the JdObject would be changed.

>>> jdo = JdObject(Julday(2007, 5, 10, 20, 15, 38), 2734.8)
>>> jd = jdo.getJd()
>>> print(jd)
 2454231.34419(2007-05-10T20:15:38.000)
>>> dat = jdo.getData()
>>> print(dat)
2734.8
getData()[source]

Return the object.

getJd()[source]

Return the time as Julday instance.

getDatetime()[source]

Return the time as datetime.datetime instance.

jd()[source]

Return the time as double-precision float.

exception irfpy.util.julday.JdSeriesKeyAlreadyExistException(value)[source]

Bases: Exception

Exception thrown when the JdSeries has data on the specified julian day

class irfpy.util.julday.JdSeries[source]

Bases: object

Map of julian day and any data (object).

The JdSeries behaves as a kind of container constituting of Julday and any type of object.

You can instance the container as

>>> ser = JdSeries()

You can add items as

>>> ser.add(Julday(2008, 12, 3, 10, 0, 0), 350.55)
>>> ser.add(Julday(2008, 12, 3, 11, 0, 0), 348.73)
>>> ser.add(Julday(2008, 12, 3, 12, 0, 0), 342.91)

You can know the size of the container.

>>> print(ser.size())
3

If you add same Julian day data, JdSeriesKeyAlreadyExistException is thrown.

>>> try:
...     ser.add(Julday(2008, 12, 3, 10, 0, 0), 328.99)
...     print('No exeption caught.  Failed')
... except JdSeriesKeyAlreadyExistException:
...     print('Exception correctly caught.  Successful.')
Exception correctly caught.  Successful.

You may get data by getNeighbor() method with specifying Julian day. You get JdObject instance.

>>> data = ser.getNeighbor(Julday(2008, 12, 3, 10, 0, 0))
>>> print(data.getJd().juld())   
2454803.91666...
>>> print(data.getData())
350.55

You can also use getNeighbor() method with specifying non-existing Julian day, but in this case, you get a data closest to the specified Julday, and execution time will be 10-100 times slower.

>>> data = ser.getNeighbor(Julday(2008, 12, 3, 10, 10, 0))
>>> print(data)
350.55 @  2454803.91667(2008-12-03T09:59:60.000)

Especially, just after adding data, getNeighbor() will be slowened because getNeighbor() must refresh an internal cache list. Therefore, data adding is recommended to be done before getting data if it allows.

To avoid this slower situation, it is recommended to use exact Julian day you specified as far as it may work. The registered Julian day list can be obtained by getJuldayList method.

>>> jdlist = ser.getJuldayList()
>>> print(len(jdlist))
3
>>> print('%r\n%r\n%r' % (jdlist[:]))
Julday(2008, 12,  3,  9, 59, 60.000)
Julday(2008, 12,  3, 11,  0, 00.000)
Julday(2008, 12,  3, 12,  0, 00.000)
>>> print(ser.getNeighbor(jdlist[2]).getData())
342.91

To obtain a set of data that includes the specified Julian day, use getBetween() method, which it is also slow.

>>> jd = ser.getNeighbor(Julday(2008, 12, 3, 11, 50, 0))
>>> print(jd)
342.91 @  2454804.00000(2008-12-03T12:00:00.000)
>>> jd0, jd1 = ser.getBetween(Julday(2008, 12, 3, 11, 50, 0))
>>> print(jd0)
348.73 @  2454803.95833(2008-12-03T11:00:00.000)
>>> print(jd1)
342.91 @  2454804.00000(2008-12-03T12:00:00.000)

You can use the iteration. The JdObject() instance is iterated.

>>> n = 0
>>> for jdo in ser:
...   n = n + 1
>>> print(n)
3

Iteration can of course be repeated.

>>> n = 0
>>> for jdo in ser:
...   print(jdo.getData())
350.55
348.73
342.91
add(jdobj_or_jd, none_or_obj=None)[source]

Add the data to the series.

If argument size is 1, the jdobj_or_jd is considered as JdObject.

If argument size is 2, the jdobj_or_jd is considered as Julday and none_or_obj is considered as Object.

clear()[source]

Clear the saved data.

>>> x = JdSeries()
>>> x.isEmpty()
True
>>> x.add(Julday(2008, 1, 2, 3, 4, 5), 300)
>>> x.isEmpty()
False
>>> x.clear()
>>> x.isEmpty()
True
jdsort()[source]

Make internal cache.

size()[source]

Returns the size of the saved data

isEmpty()[source]

Return ture if the container size is 0

first()[source]

Return the first JdObject

firstJd()[source]

Return the first Julday

last()[source]

Return the last JdObject

lastJd()[source]

Return the last Julday

getJdList()[source]

Return the sorted list of julian day in double precision float

getJuldayList()[source]

Return the sorted list of julian day (Julday instances).

This is rather expensive calculations. Using getJdList() that returns the float array is faster.

getDatetimeList()[source]

Return the sorted list of datatime.datetime instance.

>>> t0 = Julday(2000, 1, 1, 0, 0, 0)
>>> t1 = Julday(2000, 3, 10, 0, 0, 0)
>>> t2 = Julday(1900, 5, 10, 0, 0, 0)
>>> ser = JdSeries()
>>> ser.add(t0, 30)
>>> ser.add(t1, 40)
>>> ser.add(t2, 50)
>>> dtlist = ser.getDatetimeList()
>>> print(dtlist[0])
1900-05-10 00:00:00
hasElement(julday)[source]

Return that the specified julian day is contained in the dataset

isIncluded(julday)[source]

Check the given julday is in the time period.

Return True if the specified julian day is included in the time period

getNeighbor(julday)[source]

Get the neighboring data for the specified Julday.

Return the JdObject that is closest data to the specified Julday. This method has been extremely slow if the specified julday is not exactly in the key. However, by using cache (_sk), the performance of multiple calls of this method are now quite quick. However, using the Julday instances returned by getJuldayList() is faster.

getBetween(julday)[source]

Return two JdObject between which the specified julday is located.

Return the 2-element array of JdObject between which the specified julday is located.

@retval JdObject0 A JdObject of the closest data before julday @retval JdObject1 A JdObject of the closest data after julday

Note that this method is extremely slow.

irfpy.util.julday.doctests()[source]