Date handling

The Date object

class*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”


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 objects interact with timedelta as datetime do.


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


Scale in which this date is represented


new_scale (str) –


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

Return type


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.



property mjd

Date in terms of MJD



classmethod now(scale='UTC')

scale (str) –


Current time in the chosen scale

Return type


classmethod range(*args, **kwargs)

See DateRange for arguments and documentation


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, 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.


>>> 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)
>>> 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
property dur

duration of the DateRange object




inclusive flag




Begining of the range




Step size, can be positive or negative




End of the range



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

  •, 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

  •, 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.


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
    '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

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 file of your package, you have to provide the import path to this database in the following fashion:

from setuptools import setup

    description="My awesome package",
    author="John Doe",
        '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”).


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


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



classmethod get(mjd: float, dbname: Optional[str] = None) beyond.dates.eop.Eop

Retrieve Earth Orientation Parameters and timescales differences for a given date

  • mjd – Date expressed as Mean Julian Date

  • dbname – Name of the database to use


Interpolated data for this particuliar MJD

Return type


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.


Decorator for registering an Eop Database


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

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