Date handling

The Date object

class beyond.dates.date.Date(*args, scale='UTC', **kwargs)

Date object

All computations and in-memory saving are made in MJD and TAI. In the current implementation, the Date object does not handle the leap second.

The constructor can take:

  • the same arguments as the standard library’s datetime object (year, month, day, hour, minute, second, microsecond)

  • MJD as float

  • MJD as int for days and float for seconds

  • a Date or datetime object

Keyword Arguments:

scale (str) – One of the following scales : “UT1”, “UTC”, “GPS”, “TDB”, “TAI”, “TT”

Examples

Date(2016, 11, 17, 19, 16, 40)
Date(2016, 11, 17, 19, 16, 40, scale="TAI")
Date(57709.804455)  # MJD
Date(57709, 69540.752649)
Date(datetime(2016, 11, 17, 19, 16, 40))  # built-in datetime object
Date.now()

Date objects interact with timedelta as datetime do.

eop

Value of the Earth Orientation Parameters for this particular date (see Earth Orientation and leap second)

scale

Scale in which this date is represented

change_scale(new_scale)
Parameters:

new_scale (str) –

Returns:

new Date object representing the same instant, with a different timescale

Return type:

Date

property datetime

Conversion of the Date object into a datetime.datetime

The resulting object is a timezone-naive instance with the same scale as the originating Date object.

property jd

Compute the Julian Date, which is the number of days from the January 1, 4712 B.C., 12:00.

Returns:

float

property mjd

Date in terms of MJD

Returns:

float

classmethod now(scale='UTC')
Parameters:

scale (str) –

Returns:

Current time in the chosen scale

Return type:

Date

classmethod range(*args, **kwargs)

See DateRange for arguments and documentation

strftime(fmt)

Format the date following the given format

classmethod strptime(data, format, scale='UTC')

Convert a string representation of a date to a Date object

class beyond.dates.date.DateRange(start, stop, step, *, inclusive=False)

Object representing a range of Date objects

Allow for manipulation of the range before any computation. It has a lenght, can be used as an iterable, and be checked against for membership.

Example

>>> start = Date(2021, 2, 9, 23, 35, 58)
>>> stop = timedelta(hours=1, minutes=1)
>>> step = timedelta(minutes=15)
>>> r = Date.range(start, stop, step)
>>> len(r)
5
>>> for d in r:  # iterable
...     print(d)
...
2021-02-09T23:35:58 UTC
2021-02-09T23:50:58 UTC
2021-02-10T00:05:58 UTC
2021-02-10T00:20:58 UTC
2021-02-10T00:35:58 UTC
>>> Date(2021, 2, 9, 23, 45) in r  # membership test
True
property dur

duration of the DateRange object

Type:

timedelta

inclusive

inclusive flag

Type:

bool

start

Begining of the range

Type:

Date

step

Step size, can be positive or negative

Type:

timedelta

stop

End of the range

Type:

Date

Earth Orientation and leap second

Input data

In order to parse Earth Orientation Parameters (EOP) input data, you can use the following classes

class beyond.dates.eop.Finals(path, encoding='ascii')

History of Earth orientation correction for IAU1980 model

Three files are available here for this model:

  • finals.all, from 1976-01-02 to present, updated weekly

  • finals.data, from 1992-01-01 to present, updated weekly

  • finals.daily, last 90 days + 90 days of prediction, updated daily

See the associated metadata for more informations about the content of these files.

class beyond.dates.eop.Finals2000A(path, encoding='ascii')

History of Earth orientation correction for IAU2000 model

Three files are available here for this model:

  • finals2000A.all, from 1976-01-02 to present, updated weekly

  • finals2000A.data, from 1992-01-01 to present, updated weekly

  • finals2000A.daily, last 90 days + 90 days of prediction, updated daily

See the associated metadata for more informations about the content of these files.

class beyond.dates.eop.TaiUtc(path, encoding='ascii')

File listing all leap seconds throught history

This file could be retrieved here, but this server seems discontinued.

Databases

Beyond provides a simple (as simplistic) database implementation for EOP : SimpleEopDatabase.

class beyond.dates.eop.SimpleEopDatabase

Simple implementation of database

Uses tai-utc.dat, finals.all and finals2000A.all files directly without caching nor interpolation.

In order to use these files, you have to provide the directory containing them as a config variable. Optionally, you can provide the type of data you want to extract from finals files (‘all’, ‘data’ or ‘daily’).

from beyond.config import config
config.update({
    'eop': {
        'folder': "/path/to/eop/data/",
        'type': "all"
    }
})

If you need/want another database engine, you just have to create a new class defining a __getitem__ method and register it under the name you wish.

There is two methods for registering a database. The first one, is via the register() decorator

from beyond.dates.eop import register

@register('sqlite')
class SqliteEnvDatabase:

    def __getitem__(self, mjd: float):

        # retrieve data
        if data is None:
            raise KeyError(mjd)

        return data

The second is via the entry point beyond.eopdb.

If you create a python package that contain an EOP database, you can declare that database directly during install time. For that, in the setup.py file of your package, you have to provide the import path to this database in the following fashion:

from setuptools import setup

setup(
    name=mypackage,
    version="12.4.beta",
    description="My awesome package",
    author="John Doe",
    ...
    entry_points={
        'beyond.eopdb': [
            "my_personnal_db = mypackage.module:MyDatabase"
        ]
    }
)

This way, the class MyDatabase will always be available to the beyond library, and will be instantiated if needed (i.e. if the dbname config variable is set to “my_personnal_db”).

Internals

In order to access different databases with the same interface, beyond uses the EopDb class. It is this class that handle registered databases, and select the activated one.

class beyond.dates.eop.EopDb

Class handling the different EOP databases available, in a simple abstraction layer.

By defining a simple parameter in the config dict, this class will handle the instanciation of the database and queries in a transparent manner.

see dbname and missing policy configurations.

DEFAULT_DBNAME = 'default'

Default name used for EOP database lookup.

MIS_DEFAULT = 'pass'

Default behaviour in case of missing value

classmethod db(dbname=None)

Retrieve the database

Parameters:

dbname – Specify the name of the database to retrieve. If set to None, take the name from the configuration (see configuration)

Returns:

object

classmethod get(mjd: float, dbname: str | None = None) Eop

Retrieve Earth Orientation Parameters and timescales differences for a given date

Parameters:
  • mjd – Date expressed as Mean Julian Date

  • dbname – Name of the database to use

Returns:

Interpolated data for this particuliar MJD

Return type:

Eop

classmethod register(klass, name='default')

Register an Eop Database

The only requirement of this database is that it should have __getitem__ method accepting MJD as float.

beyond.dates.eop.register(name='default')

Decorator for registering an Eop Database

Example:

@register
class SqliteEnvDatabase:
    # sqlite implementation
    # this database will be known as 'default'

@register('json')
class JsonEnvDatabase:
    # JSON implementation

EopDb.get(58090.2)                    # get Eop from SqliteEnvDatabase
EopDb.get(58090.2, dbname='default')  # same as above
EopDb.get(58090.2, dbname='json')     # get Eop from JsonEnvDatabase