gpstime 0.8.2__py3-none-any.whl → 0.9.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
gpstime/__init__.py CHANGED
@@ -23,6 +23,7 @@ from datetime import datetime
23
23
  import argparse
24
24
  import subprocess
25
25
 
26
+ from dateutil.parser import parse as duparse
26
27
  from dateutil.tz import tzutc, tzlocal
27
28
 
28
29
  try:
@@ -81,32 +82,26 @@ def _cu_date_parse(string='now'):
81
82
 
82
83
  """
83
84
  cmd = ['date', '+%s.%N', '-d', string]
84
- try:
85
- ts = subprocess.check_output(cmd, stderr=subprocess.PIPE).strip()
86
- except (FileNotFoundError, subprocess.CalledProcessError) as e:
87
- raise GPSTimeException("could not parse string '{}'".format(string)) from e
88
- return float(ts)
85
+ return float(subprocess.check_output(cmd, stderr=subprocess.PIPE).strip())
89
86
 
90
87
 
91
88
  def _du_date_parse(string='now'):
92
89
  """Parse date/time string to UNIX timestamp with dateutils parse
93
90
 
94
91
  """
95
- from dateutil.parser import parse
96
- try:
97
- ts = parse(string).timestamp()
98
- except Exception as e:
99
- raise GPSTimeException("could not parse string '{}'".format(string)) from e
100
- return float(ts)
92
+ return float(duparse(string).timestamp())
101
93
 
102
94
 
103
- # test which date string parser to use. default to coreutils date if
104
- # available, since it has a better parser.
105
- try:
106
- _cu_date_parse()
107
- _date_parse = _cu_date_parse
108
- except GPSTimeException:
109
- _date_parse = _du_date_parse
95
+ def _date_parse(string="now"):
96
+ """Parse date/time string to UNIX timestamp"""
97
+ try:
98
+ ts = _du_date_parse(string)
99
+ except Exception:
100
+ try:
101
+ ts = _cu_date_parse(string)
102
+ except Exception:
103
+ raise GPSTimeException("could not parse string '{}'".format(string)) from None
104
+ return ts
110
105
 
111
106
 
112
107
  ##################################################
@@ -153,13 +148,23 @@ class gpstime(datetime):
153
148
  """Return gpstime object corresponding to GPS time."""
154
149
  return cls.fromtimestamp(gps2unix(gps), tz=tzutc())
155
150
 
151
+ @classmethod
152
+ def fromgpsns(cls, gps):
153
+ """Return gpstime object corresponding to GPS time in nanoseconds."""
154
+ try:
155
+ gps = int(gps)
156
+ except ValueError:
157
+ raise GPSTimeException("Provided value is not an integer")
158
+ gps /= 1_000_000_000
159
+ return cls.fromgps(gps)
160
+
156
161
  @classmethod
157
162
  def parse(cls, string='now'):
158
- """Parse an arbitrary time string into a gpstime object.
163
+ """Parse an arbitrary time string/float into a gpstime object.
159
164
 
160
165
  If string not specified 'now' is assumed. Strings that can be
161
- cast to float are assumed to be GPS times. Prepend '@' to a
162
- float to specify a UNIX timestamp.
166
+ cast to a float are assumed to be GPS times. Prepend '@' to a
167
+ float string to specify a UNIX timestamp.
163
168
 
164
169
  This parse uses the natural lanuage parsing abilities of the
165
170
  GNU coreutils 'date' utility. See "DATE STRING" in date(1)
@@ -216,7 +221,7 @@ def gpsnow():
216
221
  """Return current GPS time as a float.
217
222
 
218
223
  """
219
- return gpstime.utcnow().replace(tzinfo=tzutc()).gps()
224
+ return unix2gps(datetime.now(tz=tzutc()).timestamp())
220
225
 
221
226
 
222
227
  parse = gpstime.parse
@@ -233,8 +238,14 @@ class GPSTimeParseAction(argparse.Action):
233
238
  # single string
234
239
  if isinstance(values, list):
235
240
  values = ' '.join(values)
236
- try:
237
- gps = parse(values)
238
- except GPSTimeException:
239
- parser.error("Could not parse date/time string '{}'".format(values))
241
+ if namespace.nano:
242
+ try:
243
+ gps = gpstime.fromgpsns(values)
244
+ except GPSTimeException as e:
245
+ parser.error(e)
246
+ else:
247
+ try:
248
+ gps = parse(values)
249
+ except GPSTimeException:
250
+ parser.error("Could not parse date/time string '{}'".format(values))
240
251
  setattr(namespace, self.dest, gps)
gpstime/__main__.py CHANGED
@@ -17,17 +17,24 @@ https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
17
17
  formatter_class=argparse.RawDescriptionHelpFormatter)
18
18
  PARSER.add_argument(
19
19
  '-v', '--version', action='version', version=__version__,
20
- help="print version number and exit")
20
+ help="show version number and exit")
21
+ # parser options
22
+ pg = PARSER.add_mutually_exclusive_group()
23
+ pg.add_argument(
24
+ '-n', '--nano', action='store_true',
25
+ help="assume time specified as integer GPS nanoseconds")
26
+ # output options
21
27
  zg = PARSER.add_mutually_exclusive_group()
22
28
  zg.add_argument(
23
29
  '-l', '--local', action='store_const', dest='tz', const='local',
24
- help="print only local time")
30
+ help="print only local time (or timezone specified with 'TZ' env var)")
25
31
  zg.add_argument(
26
32
  '-u', '--utc', action='store_const', dest='tz', const='utc',
27
33
  help="print only UTC time")
28
34
  zg.add_argument(
29
35
  '-g', '--gps', action='store_const', dest='tz', const='gps',
30
36
  help="print only GPS time")
37
+ # format options
31
38
  fg = PARSER.add_mutually_exclusive_group()
32
39
  fg.add_argument(
33
40
  '-i', '--iso', action='store_const', dest='format', const=ISO_FORMAT,
gpstime/__version__.py CHANGED
@@ -1,16 +1,34 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
3
13
  TYPE_CHECKING = False
4
14
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
15
+ from typing import Tuple
16
+ from typing import Union
17
+
6
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
7
20
  else:
8
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
9
23
 
10
24
  version: str
11
25
  __version__: str
12
26
  __version_tuple__: VERSION_TUPLE
13
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '0.9.0'
32
+ __version_tuple__ = version_tuple = (0, 9, 0)
14
33
 
15
- __version__ = version = '0.8.2'
16
- __version_tuple__ = version_tuple = (0, 8, 2)
34
+ __commit_id__ = commit_id = 'gbfcac2c49'
gpstime/leaps.py CHANGED
@@ -6,10 +6,11 @@ import warnings
6
6
  from tempfile import NamedTemporaryFile
7
7
  from functools import lru_cache
8
8
 
9
- import appdirs
10
-
11
-
12
- CACHE_DIR = appdirs.user_cache_dir('gpstime')
9
+ try:
10
+ from platformdirs import user_cache_dir
11
+ except ImportError:
12
+ from appdirs import user_cache_dir
13
+ CACHE_DIR = user_cache_dir('gpstime')
13
14
 
14
15
  LEAP_FILES = [
15
16
  '/usr/share/zoneinfo/leap-seconds.list',
@@ -235,8 +236,7 @@ def find_leap_data(download=None):
235
236
  return leapdata
236
237
 
237
238
  if download is not False:
238
- if not os.path.exists(CACHE_DIR):
239
- os.makedirs(CACHE_DIR)
239
+ os.makedirs(CACHE_DIR, exist_ok=True)
240
240
 
241
241
  for remote in SOURCES:
242
242
  print(f"Attempting to update user leap data cache from {remote}...", file=sys.stderr)
@@ -261,8 +261,6 @@ def find_leap_data(download=None):
261
261
  os.remove(temp_path)
262
262
  continue
263
263
 
264
- if os.path.exists(path):
265
- os.remove(path)
266
264
  os.rename(temp_path, path)
267
265
 
268
266
  if leapdata.valid:
gpstime/test.py CHANGED
@@ -1,6 +1,7 @@
1
+ import datetime
1
2
  import unittest
3
+ import shutil
2
4
  import sys
3
- import datetime
4
5
 
5
6
  from dateutil.tz import tzutc
6
7
 
@@ -10,11 +11,9 @@ import gpstime
10
11
 
11
12
  def cu_date_available():
12
13
  """return True if coreutils date parser available"""
13
- try:
14
- gpstime._cu_date_parse()
14
+ if shutil.which("date"):
15
15
  return True
16
- except:
17
- return False
16
+ return False
18
17
 
19
18
 
20
19
  class TestGPStime(unittest.TestCase):
@@ -131,10 +130,29 @@ class TestGPStime(unittest.TestCase):
131
130
  self.assertEqual(gpstime.gpstime.fromgps(1133585676.874).iso(),
132
131
  '2015-12-08T04:54:19.874000Z')
133
132
 
133
+ @unittest.skipIf(not cu_date_available(), "coreutils date not available")
134
+ def test_non_standard_iso_format(self):
135
+ """ Tests whether dates with '/' separators are parsed as iso dates.
136
+ Core utils instead parses them as if the 'T' character meant
137
+ a military time zone.
138
+ """
139
+
140
+ # both date utils and core utils will parse this using the default timezone
141
+ self.assertEqual(gpstime.gpstime.parse('2025-02-08T04:54:19'),
142
+
143
+ # date utils will also parse this using the default time zone
144
+ # but core utils will parse this using the military timezone 'T'
145
+ gpstime.gpstime.parse('2025/02/08T04:54:19'))
146
+
147
+
134
148
  def test_gpstime_fromgps_timestamp(self):
135
149
  self.assertEqual(gpstime.gpstime.fromgps(1133585676).timestamp(),
136
150
  1449550459)
137
151
 
152
+ def test_gpstime_fromgpsns_timestamp(self):
153
+ self.assertEqual(gpstime.gpstime.fromgpsns(1133585676200000000).gps(),
154
+ 1133585676.2)
155
+
138
156
  def test_gpstime_tconvert_classmethod(self):
139
157
  self.assertEqual(gpstime.gpstime.tconvert(1133585676.2).gps(),
140
158
  1133585676.2)
@@ -1,26 +1,24 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: gpstime
3
- Version: 0.8.2
3
+ Version: 0.9.0
4
4
  Summary: GPS-aware datetime module
5
- Home-page: https://git.ligo.org/cds/gpstime
6
- Author: Jameson Graef Rollins
7
- Author-email: jameson.rollins@ligo.org
8
- License: GPL-3.0-or-later
5
+ Author-email: Jameson Graef Rollins <jameson.rollins@ligo.org>
6
+ License-Expression: GPL-3.0-or-later
7
+ Project-URL: Homepage, https://git.ligo.org/cds/software/gpstime
9
8
  Classifier: Development Status :: 5 - Production/Stable
10
- Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
11
9
  Classifier: Natural Language :: English
12
10
  Classifier: Operating System :: OS Independent
13
11
  Classifier: Programming Language :: Python
14
- Classifier: Programming Language :: Python :: 2.7
15
- Classifier: Programming Language :: Python :: 3.5
16
- Classifier: Programming Language :: Python :: 3.6
17
- Classifier: Programming Language :: Python :: 3.7
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.6
18
14
  Description-Content-Type: text/markdown
19
15
  License-File: COPYING
20
16
  License-File: COPYING-GPL-3
21
- Requires-Dist: appdirs
17
+ Requires-Dist: platformdirs; python_version >= "3.10"
18
+ Requires-Dist: appdirs; python_version < "3.10"
22
19
  Requires-Dist: python-dateutil
23
20
  Requires-Dist: requests
21
+ Dynamic: license-file
24
22
 
25
23
  GPS-aware datetime module
26
24
  =========================
@@ -0,0 +1,12 @@
1
+ gpstime/__init__.py,sha256=fre95_2UeDNSeb3kS3JebJOh9Bn30iLVZQh-Juch_AI,7284
2
+ gpstime/__main__.py,sha256=ndEEI2WAOkZzQrwQ7zJs0nbTsMTpIutGyoZR_Tr6DYE,2882
3
+ gpstime/__version__.py,sha256=Zco1Vyuo5sw4puW8I8qiB87z9_37yhdD3y1klzVfvHg,712
4
+ gpstime/leaps.py,sha256=QduewuPZce_BpbB5zkMR4c_sZeATn1oD7XuPIECRpOQ,7825
5
+ gpstime/test.py,sha256=0NZVr46dAuxn1gYUMJtU89z0Kd5bn8S7lJAUzPujbns,7845
6
+ gpstime-0.9.0.data/scripts/gpstime,sha256=R2M1Xg02MAqpiPWxuOoSYr3S8zk7aPtfeHBmMG-1jMo,183
7
+ gpstime-0.9.0.dist-info/licenses/COPYING,sha256=kD3Y57xS042kgHR4KTOzNOiOHLxiOtxwe2gomX6l0cM,1724
8
+ gpstime-0.9.0.dist-info/licenses/COPYING-GPL-3,sha256=_ILKi2_bGNTj6Fz9irWNG80_Gymr54KJWr2R1kdj-Oc,35068
9
+ gpstime-0.9.0.dist-info/METADATA,sha256=L2SBzlWvNP6GRjB_qC8EQPOTzVJo-ZwMeWZGJ59uoNE,1477
10
+ gpstime-0.9.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
11
+ gpstime-0.9.0.dist-info/top_level.txt,sha256=LJlZJoesrJMc-u-T2IuSXd6udNzp1TaVD6aJa5Zwj54,8
12
+ gpstime-0.9.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (70.3.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,12 +0,0 @@
1
- gpstime/__init__.py,sha256=mvvNkbLXi2Ego2INs97qUZz4vmmuo5WZ55IlYiOhwIc,6950
2
- gpstime/__main__.py,sha256=_sCWDDruEWZOrkorMeQkOwIVcWAOfzA5VSuTpuG3iNs,2628
3
- gpstime/__version__.py,sha256=t6tJJG56wlBKsg_0M1Q4l1ir09jgXRw1tolMbDalW9g,411
4
- gpstime/leaps.py,sha256=yc8rjaF8fqvrL1ytNffj2PbibyW-J0BPpmI7oOPJn4I,7842
5
- gpstime/test.py,sha256=74rbEBOnQIEhE96VPiTZqekbwRoumeNqgj3rXHILGpw,7010
6
- gpstime-0.8.2.data/scripts/gpstime,sha256=R2M1Xg02MAqpiPWxuOoSYr3S8zk7aPtfeHBmMG-1jMo,183
7
- gpstime-0.8.2.dist-info/COPYING,sha256=kD3Y57xS042kgHR4KTOzNOiOHLxiOtxwe2gomX6l0cM,1724
8
- gpstime-0.8.2.dist-info/COPYING-GPL-3,sha256=_ILKi2_bGNTj6Fz9irWNG80_Gymr54KJWr2R1kdj-Oc,35068
9
- gpstime-0.8.2.dist-info/METADATA,sha256=9gLonvhIzkqc5GRV98P9Q62fCiwLXwQbHGGdXXlAOfI,1566
10
- gpstime-0.8.2.dist-info/WHEEL,sha256=Z4pYXqR_rTB7OWNDYFOm1qRk0RX6GFP2o8LgvP453Hk,91
11
- gpstime-0.8.2.dist-info/top_level.txt,sha256=LJlZJoesrJMc-u-T2IuSXd6udNzp1TaVD6aJa5Zwj54,8
12
- gpstime-0.8.2.dist-info/RECORD,,