Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 106 additions & 19 deletions doc/source/getting_started/Getting-Started.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "markdown",
"id": "2e01086c",
"id": "382d354c",
"metadata": {},
"source": [
"# Getting Started\n",
Expand All @@ -21,8 +21,111 @@
"- **TAI time**: International Atomic Time which is computed as the weighted average of several hundred atomic clocks.\n",
"- **UTC time**: Coordinated Universal Time which is [periodically adjusted](https://www.nist.gov/pml/time-and-frequency-division/leap-seconds-faqs) to account for the difference between the definition of the second and the rotation of Earth.\n",
"- **GPS time**: Atomic timing system for the Global Positioning System constellation of satellites monitored by the United States Naval Observatory (USNO). GPS time and UTC time were equal on January 6, 1980. TAI time is ahead of GPS time by 19 seconds.\n",
"- **LORAN time**: Atomic timing system for the Loran-C chain transmitter sites used in terrestrial radionavigation. LORAN time and UTC time were equal on January 1, 1958. TAI time is ahead of LORAN time by 10 seconds.\n",
"\n",
"- **LORAN time**: Atomic timing system for the Loran-C chain transmitter sites used in terrestrial radionavigation. LORAN time and UTC time were equal on January 1, 1958. TAI time is ahead of LORAN time by 10 seconds."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5ccc6e80",
"metadata": {
"tags": [
"remove-input"
]
},
"outputs": [],
"source": [
"import datetime\n",
"import timescale\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import matplotlib.dates as mdates\n",
"\n",
"# adjust style\n",
"facecolor = \"#fcfcfc\"\n",
"plt.rcParams[\"figure.facecolor\"] = facecolor\n",
"plt.rcParams[\"font.family\"] = \"sans-serif\"\n",
"plt.rcParams[\"font.sans-serif\"] = [\"Lato\"]\n",
"\n",
"# build a monthly time axis for plotting\n",
"today = datetime.date.today().isoformat()\n",
"ts = timescale.from_range(\"1972-01-01\", today, 1, \"D\")\n",
"dt = ts.to_datetime()\n",
"\n",
"# create figure\n",
"fig, ax = plt.subplots(figsize=(8, 4.5))\n",
"# add differences between timescales\n",
"ax.plot(\n",
" dt,\n",
" np.zeros_like(ts.utc),\n",
" color=\"0.4\",\n",
" lw=1.5,\n",
" label=\"UTC\",\n",
" zorder=0,\n",
")\n",
"ax.plot(\n",
" dt,\n",
" ts.ut1_utc,\n",
" color=\"red\",\n",
" lw=1.5,\n",
" label=\"UT1\\u2013UTC\",\n",
" zorder=2,\n",
")\n",
"ax.plot(\n",
" dt,\n",
" ts.gps_utc,\n",
" color=\"dodgerblue\",\n",
" lw=1.5,\n",
" label=\"GPS\\u2013UTC\",\n",
" zorder=1,\n",
")\n",
"ax.plot(\n",
" dt,\n",
" ts.loran_utc,\n",
" color=\"mediumseagreen\",\n",
" lw=1.5,\n",
" label=\"LORAN\\u2013UTC\",\n",
")\n",
"ax.plot(\n",
" dt,\n",
" ts.tai_utc,\n",
" color=\"darkorchid\",\n",
" lw=1.5,\n",
" label=\"TAI\\u2013UTC\",\n",
")\n",
"# show maximum range of UT1 variability\n",
"ax.axhline(0.9, color=\"k\", lw=0.7, ls=\"--\")\n",
"ax.axhline(-0.9, color=\"k\", lw=0.7, ls=\"--\")\n",
"ax.text(\n",
" dt[-100],\n",
" 1.0,\n",
" r\"$\\pm 0.9$s DUT1 limit\",\n",
" color=\"k\",\n",
" ha=\"right\",\n",
" va=\"bottom\",\n",
" fontsize=9,\n",
")\n",
"# add legend\n",
"lgd = ax.legend(frameon=False)\n",
"for line in lgd.get_lines():\n",
" line.set_linewidth(6)\n",
"# add labels\n",
"ax.set_ylabel(\"Offset relative to UTC [s]\")\n",
"ax.set_xlabel(\"Time [yr]\")\n",
"# set limits and tick locations\n",
"ax.set_xlim(dt[0], dt[-1])\n",
"ax.xaxis.set_major_locator(mdates.YearLocator(5))\n",
"ax.xaxis.set_major_formatter(mdates.DateFormatter(\"%Y\"))\n",
"# set layout\n",
"fig.tight_layout()\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "2e01086c",
"metadata": {},
"source": [
"### Dynamic Time\n",
"\n",
"`timescale` also keeps updated tables of delta times for converting between dynamic (TT) and universal (UT1) times.\n",
Expand All @@ -47,22 +150,6 @@
"5. Julian dates "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "67db92dc",
"metadata": {
"tags": [
"remove-input"
]
},
"outputs": [],
"source": [
"import datetime\n",
"import numpy as np\n",
"import timescale.time"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
26 changes: 23 additions & 3 deletions timescale/time.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

UPDATE HISTORY:
Updated 07/2026: add HTML representations of Timescale and Calendar
added attributes for tai_utc and loran_utc
Updated 05/2026: added functions to update delta time files from project
updated CDDIS ftp login options for encrypted connections
Updated 04/2026: added endpoint option (defaults to True) to date_range
Expand Down Expand Up @@ -1104,6 +1105,12 @@ def gps_week(self):
"""GPS week number since 1980-01-06T00:00:00"""
return (self.gps / (self.day * 7)).astype(np.int64)

@timescale.utilities.reify
def loran_utc(self):
"""Leap seconds between LORAN and UTC time"""
# LORAN time is behind of TAI time by 10 seconds
return self.tai_utc - 10.0

@timescale.utilities.reify
def J2000(self):
"""Seconds (Terrestrial Time) since 2000-01-01T12:00:00"""
Expand All @@ -1127,6 +1134,21 @@ def st(self):
np.mod(ST + self.era * self.deg2asec, self.turnasec) / self.turnasec
)

@timescale.utilities.reify
def tai_utc(self):
"""Leap seconds between TAI and UTC time"""
# dynamic time is ahead of TAI by 32.184 seconds
_tt_tai = 32.184
# TAI time is ahead of GPS by 19 seconds
_tai_gps = 19.0
# number of leap seconds at the start of the GPS epoch
_leaps_gps = 10.0
# convert from dynamic time to TAI
TAI = np.atleast_1d(self.tt - _jd_gps) * self.day - _tt_tai
# calculate the number of leap seconds
leaps = count_leap_seconds(TAI - _tai_gps, truncate=False)
return leaps - _leaps_gps + _tai_gps

@timescale.utilities.reify
def tdb(self):
"""Approximate Barycentric Dynamical Time (TDB) as Julian Days"""
Expand Down Expand Up @@ -1178,12 +1200,10 @@ def ut1_utc(self):
"""
# dynamic time is ahead of TAI by 32.184 seconds
_tt_tai = 32.184
# TAI time is ahead of GPS by 19 seconds
_tai_gps = 19.0
# convert from delta times back to seconds
_tt_ut1 = self.day * self.tt_ut1
# recalculate UT1-UTC (seconds)
return _tt_tai + _tai_gps + self.gps_utc - _tt_ut1
return _tt_tai + self.tai_utc - _tt_ut1

@timescale.utilities.reify
def T(self):
Expand Down
Loading