-
Notifications
You must be signed in to change notification settings - Fork 0
/
DAQTime.py
130 lines (98 loc) · 3.8 KB
/
DAQTime.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python
from __future__ import print_function
import datetime
import numbers
import re
import sys
from HsException import HsException
from leapseconds import LeapSeconds
if sys.version_info >= (3, 0):
# pylint: disable=invalid-name
# unicode isn't present in Python3
unicode = str
# dictionary which maps year to the datetime object for January 1 of that year
JAN1 = {}
# format string used to parse dates
TIME_FORMAT = "%Y-%m-%d %H:%M:%S.%f"
def jan1_by_year(daq_time=None):
"""
Return the datetime value for January 1 of the specified year.
If year is None, return January 1 for the current year.
"""
if daq_time is not None:
year = daq_time.year
else:
year = datetime.datetime.utcnow().year
if year not in JAN1:
JAN1[year] = datetime.datetime(year, 1, 1)
return JAN1[year]
def ticks_to_utc(ticks):
"Convert an integral DAQ tick value to a time object"
if ticks is None:
raise HsException("No tick value specified")
if not isinstance(ticks, numbers.Number):
raise HsException("Tick value %s should be number, not %s" %
(ticks, type(ticks).__name__))
return jan1_by_year() + datetime.timedelta(seconds=ticks / 1E10)
def string_to_ticks(timestr, is_ns=False):
"Convert a time string to an integral DAQ tick value"
if timestr is None:
raise HsException("Found null value for start/stop time in %s" %
(timestr, ))
multiplier = 10 if is_ns else 1
if isinstance(timestr, numbers.Number):
return int(timestr * multiplier)
if isinstance(timestr, (str, unicode)):
if timestr.isdigit():
try:
return int(timestr) * multiplier
except:
raise HsException("Cannot convert \"%s\" to ticks" %
(timestr, ))
try:
utc = datetime.datetime.strptime(timestr, TIME_FORMAT)
except ValueError:
# Python date parser can only handle milliseconds
if timestr.find(".") > 0:
short = re.sub(r"(\.\d{6})\d+", r"\1", timestr)
try:
utc = datetime.datetime.strptime(short, TIME_FORMAT)
except:
raise HsException("Cannot convert \"%s\" to datetime" %
(timestr, ))
elif TIME_FORMAT.endswith(".%f"):
shortfmt = TIME_FORMAT[:-3]
try:
utc = datetime.datetime.strptime(timestr, shortfmt)
except:
raise HsException("Cannot convert \"%s\" to datetime" %
(timestr, ))
return utc_to_ticks(utc)
raise HsException("Cannot convert %s(%s) to ticks" %
(type(timestr).__name__, timestr))
def utc_to_ticks(utc):
"""
Get the number of 0.1ns ticks (since Jan 1) for the 'utc' datetime
"""
delta = utc - jan1_by_year(utc)
# get the number of leap seconds (0 or 1) since the start of the year
leap = LeapSeconds.instance()
jan1_leapsecs = leap.get_leap_offset(0, year=utc.year)
utc_leapsecs = leap.get_leap_offset(delta.days, year=utc.year)
extrasecs = utc_leapsecs - jan1_leapsecs
return int(((delta.days * 24 * 3600 + delta.seconds + extrasecs) *
1000000 + delta.microseconds) * 10000)
def main():
"Main program"
is_ns = False
for arg in sys.argv[1:]:
if arg == "-n":
is_ns = True
continue
ticks = string_to_ticks(arg, is_ns=is_ns)
utc = ticks_to_utc(ticks)
tick2 = utc_to_ticks(utc)
print("Arg \"%s\"\n\t-> ticks %s\n\t->utc \"%s\"\n\t-> ticks %s" %
(arg, ticks, utc, tick2))
if __name__ == "__main__":
main()