LAL  7.5.0.1-bede9b2
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
20 package
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 
41 import datetime as _datetime
42 from decimal import Decimal
43 from numbers import Number
44 
45 from dateutil.parser import parse as str_to_utc
46 
47 from .lal import (
48  LIGOTimeGPS,
49  GPSTimeNow as _gps_time_now,
50  GPSToUTC as _gps_to_utc,
51  UTCToGPS as _utc_to_gps,
52 )
53 from . import git_version
54 
55 __author__ = "Duncan Macleod <duncan.macleod@ligo.org>"
56 __version__ = git_version.verbose_msg
57 __date__ = git_version.date
58 
59 TIME_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 }
72 GPS_EPOCH = _datetime.datetime(1980, 1, 6, 0, 0, 0)
73 LAL_GPS_MAX = _datetime.datetime(2048, 1, 24, 3, 13, 55)
74 
75 
76 def _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 
87 def gps_time_now():
88  """Get the current time in GPS seconds
89 
90  @returns a LIGOTimeGPS
91  """
92  return _gps_time_now()
93 
94 
95 def 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 
106 def 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 
124 def 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 
132 def 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 
171 def 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 
195 def 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 
230 if __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)
onvert 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