Loading [MathJax]/extensions/TeX/AMSsymbols.js
LAL 7.7.0.1-3a66518
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
gpstime.py
Go to the documentation of this file.
1# Copyright (C) 2021 Cardiff University
2#
3# This program is free software; you can redistribute it and/or modify it
4# under the terms of the GNU General Public License as published by the
5# Free Software Foundation; either version 3 of the License, or (at your
6# option) any later version.
7#
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11# Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along
14# with this program; if not, write to the Free Software Foundation, Inc.,
15# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
17## \defgroup lal_py_gpstime GPSTime
18## \ingroup lal_python
19"""Utilties for calculating and modifying GPS times using the LAL date
20package
21"""
22#
23# ### Synopsis ###
24#
25# ~~~
26# from lal import gpstime
27# ~~~
28# This module wraps the LAL \ref Date_h module into Python providing
29# functions to convert from the `datetime.datetime` objects from the
30# Python standard library into LIGOTimeGPS numbers, and vice-versa.
31# See in particular ::gps_to_utc and ::utc_to_gps.
32#
33# This module also provides a Python implementation of the `tconvert'
34# module, allowing conversion from strings of dates and times into
35# LIGOTimeGPS, and vice-versa. See in particular ::gps_to_str and
36# ::str_to_gps.
37#
38# \author Duncan Macleod <duncan.macleod@ligo.org>
39#@{
40
41import datetime as _datetime
42from decimal import Decimal
43from numbers import Number
44
45from dateutil.parser import parse as str_to_utc
46
47from .lal import (
48 LIGOTimeGPS,
49 GPSTimeNow as _gps_time_now,
50 GPSToUTC as _gps_to_utc,
51 UTCToGPS as _utc_to_gps,
52)
53from . import git_version
54
55__author__ = "Duncan Macleod <duncan.macleod@ligo.org>"
56__version__ = git_version.verbose_msg
57__date__ = git_version.date
58
59TIME_ZONES = {
60 "PST": -8*3600,
61 "PDT": -7*3600,
62 "CST": -6*3600,
63 "CDT": -5*3600,
64 "EST": -5*3600,
65 "EDT": -4*3600,
66 "GMT": 0,
67 "UTC": 0,
68 "BST": 1*3600,
69 "CET": 1*3600,
70 "CEST": 2*3600,
71}
72GPS_EPOCH = _datetime.datetime(1980, 1, 6, 0, 0, 0)
73LAL_GPS_MAX = _datetime.datetime(2048, 1, 24, 3, 13, 55)
74
75
76def _check_utc(utc_time):
77 """Check whether this UTC datetime will convert to a valid LIGOTimeGPS
78 """
79 if utc_time < GPS_EPOCH:
80 raise ValueError("Given UTC time is before the start of the GPS era.")
81 if utc_time > LAL_GPS_MAX:
82 raise ValueError("Given UTC time is too far in the future, "
83 "LAL will SegmentationFault.")
84 return
85
86
87def gps_time_now():
88 """Get the current time in GPS seconds
89
90 @returns a LIGOTimeGPS
91 """
92 return _gps_time_now()
93
94
95def utc_to_gps(utc_time):
96 """Convert the given `datetime.datetime` into a GPS time
97
98 @returns a LIGOTimeGPS
99 """
100 if not isinstance(utc_time, _datetime.datetime):
101 utc_time = _datetime.datetime.combine(utc_time, _datetime.time())
102 _check_utc(utc_time)
103 return LIGOTimeGPS(_utc_to_gps(utc_time.utctimetuple()))
104
105
106def gps_to_utc(gps):
107 """Convert a GPS time into a `datetime.datetime`
108
109 @returns a Python `datetime.datetime` object in UTC
110 """
111 if isinstance(gps, (Decimal, Number)):
112 gps = str(gps)
113 gps = LIGOTimeGPS(gps)
114 dt = _datetime.datetime(
115 *_gps_to_utc(gps.gpsSeconds)[:7]
116 ).replace(microsecond=0) # force microseconds to 0
117 if gps.gpsNanoSeconds:
118 return dt.replace(
119 microsecond=int(round(gps.gpsNanoSeconds * 1e-3)),
120 )
121 return dt
122
123
124def utc_time_now():
125 """Get the current date and time in UTC
126
127 @returns a Python `datetime.datetime` object in UTC
128 """
129 return gps_to_utc(_gps_time_now())
130
131
132def str_to_gps(time_string=None):
133 r"""Converts a date/time string into a GPS time.
134
135 The following special words are permitted:
136 - "now"
137 - "today"
138 - "yesterday"
139 - "tomorrow"
140
141 Example:
142 \code
143 >>> gpstime.str_to_gps("September 14 2011, 01:46:25")
144 1000000000.000000000
145 \endcode
146
147 @returns a LIGOTimeGPS
148 """
149 if not time_string or time_string.lower() == "now":
150 return _gps_time_now()
151 elif time_string == "today":
152 date = _datetime.date.today()
153 return utc_to_gps(_datetime.datetime.combine(date, _datetime.time()))
154 elif time_string == "tomorrow":
155 today = _datetime.datetime.combine(_datetime.date.today(),
156 _datetime.time())
157 tomorrow = today + _datetime.timedelta(days=1)
158 return utc_to_gps(tomorrow)
159 elif time_string == "yesterday":
160 today = _datetime.datetime.combine(_datetime.date.today(),
161 _datetime.time())
162 yesterday = today - _datetime.timedelta(days=1)
163 return utc_to_gps(yesterday)
164 # otherwise parse the string as a date/time
165 utc = str_to_utc(time_string, tzinfos=TIME_ZONES)
166 micro = utc.microsecond
167 gps = utc_to_gps(utc)
168 return gps + micro / 1000000.0
169
170
171def gps_to_str(gps, form=None):
172 r"""
173 Convert a LIGOTimeGPS time object into a string.
174 The output format can be given explicitly, but will default
175 as shown in the example.
176
177 Example:
178
179 \code
180 >>> gps_to_str(1000000000)
181 'September 14 2011, 01:46:25 UTC'
182 \endcode
183
184 @returns a string with the given format.
185 """
186 gps = LIGOTimeGPS(gps)
187 utc = gps_to_utc(gps)
188 if gps.gpsNanoSeconds and not form:
189 form = "%B %d %Y, %H:%M:%S.%f UTC"
190 elif not form:
191 form = "%B %d %Y, %H:%M:%S UTC"
192 return utc.strftime(form)
193
194
195def tconvert(arg=None, form=None):
196 r"""Convert date/time strings to and from GPS times.
197 If no argument is given, the current GPS time is returned.
198
199 The following special words are permitted:
200 - "now"
201 - "today"
202 - "yesterday"
203 - "tomorrow"
204
205 Example:
206
207 \code
208 >>> tconvert()
209 1048275013.000000000
210 >>> tconvert("January 6 1980 00:00:00")
211 0.000000000
212 >>> tconvert(1000000000)
213 'September 14 2011, 01:46:25 UTC'
214 \endcode
215
216 @returns the LIGOTimeGPS of the given time string, OR, string
217 representing the given GPS time
218 """
219 try:
220 float(arg)
221 except ValueError:
222 return str_to_gps(arg)
223 else:
224 return gps_to_str(arg, form=form)
225
226
227##@}
228
229
230if __name__ == "__main__":
231 now = tconvert()
232 now_utc = gps_to_str(now)
233 print("The date/time now is %s (%d)" % (now_utc, now))
static int replace(int c, void *param)
Definition: LALString.c:373
def str_to_gps(time_string=None)
Converts a date/time string into a GPS time.
Definition: gpstime.py:148
def tconvert(arg=None, form=None)
Convert date/time strings to and from GPS times.
Definition: gpstime.py:218
def gps_time_now()
Get the current time in GPS seconds.
Definition: gpstime.py:91
def gps_to_str(gps, form=None)
Convert a LIGOTimeGPS time object into a string.
Definition: gpstime.py:185
def utc_time_now()
Get the current date and time in UTC.
Definition: gpstime.py:128
def utc_to_gps(utc_time)
Convert the given datetime.datetime into a GPS time.
Definition: gpstime.py:99
def gps_to_utc(gps)
Convert a GPS time into a datetime.datetime
Definition: gpstime.py:110