# # NT Time utility functions. # # Copyright (C) Catalyst.Net Ltd 2023 # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import datetime from typing import NewType NtTime = NewType("NtTime", int) NtTimeDelta = NewType("NtTimeDelta", int) NT_EPOCH = datetime.datetime( 1601, 1, 1, 0, 0, 0, 0, tzinfo=datetime.timezone.utc ) NT_TICKS_PER_μSEC = 10 NT_TICKS_PER_SEC = NT_TICKS_PER_μSEC * 10**6 def _validate_nt_time(nt_time: NtTime) -> None: if not isinstance(nt_time, int): raise ValueError(f"{nt_time} is not an integer") if not 0 <= nt_time < 2**64: raise ValueError(f"{nt_time} is out of range") def nt_time_from_datetime(tm: datetime.datetime) -> NtTime: time_since_epoch = tm - NT_EPOCH nt_time = NtTime(round(time_since_epoch.total_seconds() * NT_TICKS_PER_SEC)) _validate_nt_time(nt_time) return nt_time def datetime_from_nt_time(nt_time: NtTime) -> datetime.datetime: _validate_nt_time(nt_time) time_since_epoch = datetime.timedelta(microseconds=nt_time / NT_TICKS_PER_μSEC) return NT_EPOCH + time_since_epoch def nt_time_delta_from_datetime(dt: datetime.timedelta) -> NtTimeDelta: return NtTimeDelta(round(dt.total_seconds() * NT_TICKS_PER_SEC)) def timedelta_from_nt_time_delta(nt_time_delta: NtTimeDelta) -> datetime.timedelta: return datetime.timedelta(microseconds=nt_time_delta / NT_TICKS_PER_μSEC)