2 # NT Time utility functions.
4 # Copyright (C) Catalyst.Net Ltd 2023
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <https://www.gnu.org/licenses/>.
21 from typing
import NewType
24 NtTime
= NewType("NtTime", int)
25 NtTimeDelta
= NewType("NtTimeDelta", int)
28 NT_EPOCH
= datetime
.datetime(
29 1601, 1, 1, 0, 0, 0, 0, tzinfo
=datetime
.timezone
.utc
31 NT_TICKS_PER_μSEC
= 10
32 NT_TICKS_PER_SEC
= NT_TICKS_PER_μSEC
* 10**6
35 def _validate_nt_time(nt_time
: NtTime
) -> None:
36 if not isinstance(nt_time
, int):
37 raise ValueError(f
"{nt_time} is not an integer")
38 if not 0 <= nt_time
< 2**64:
39 raise ValueError(f
"{nt_time} is out of range")
42 def nt_time_from_datetime(tm
: datetime
.datetime
) -> NtTime
:
43 time_since_epoch
= tm
- NT_EPOCH
44 nt_time
= NtTime(round(time_since_epoch
.total_seconds() * NT_TICKS_PER_SEC
))
45 _validate_nt_time(nt_time
)
49 def datetime_from_nt_time(nt_time
: NtTime
) -> datetime
.datetime
:
50 _validate_nt_time(nt_time
)
51 time_since_epoch
= datetime
.timedelta(microseconds
=nt_time
/ NT_TICKS_PER_μSEC
)
52 return NT_EPOCH
+ time_since_epoch
55 def nt_time_delta_from_datetime(dt
: datetime
.timedelta
) -> NtTimeDelta
:
56 return NtTimeDelta(round(dt
.total_seconds() * NT_TICKS_PER_SEC
))
59 def timedelta_from_nt_time_delta(nt_time_delta
: NtTimeDelta
) -> datetime
.timedelta
:
60 return datetime
.timedelta(microseconds
=nt_time_delta
/ NT_TICKS_PER_μSEC
)