1# Copyright 2022 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Library to analyze timestamp.""" 15 16import datetime 17from pw_chrono_protos import chrono_pb2 18 19_UTC_EPOCH = datetime.datetime(1970, 1, 1, 00, 00, 00) 20 21_UNKNOWN = chrono_pb2.EpochType.Enum.UNKNOWN 22_TIME_SINCE_BOOT = chrono_pb2.EpochType.Enum.TIME_SINCE_BOOT 23_UTC_WALL_CLOCK = chrono_pb2.EpochType.Enum.UTC_WALL_CLOCK 24 25 26def process_snapshot(serialized_snapshot: bytes): 27 captured_timestamps = chrono_pb2.SnapshotTimestamps() 28 captured_timestamps.ParseFromString(serialized_snapshot) 29 return timestamp_output(captured_timestamps) 30 31 32def timestamp_output(timestamps: chrono_pb2.SnapshotTimestamps): 33 output: list[str] = [] 34 if not timestamps.timestamps: 35 return '' 36 37 plural = '' if len(timestamps.timestamps) == 1 else 's' 38 output.append(f'Snapshot capture timestamp{plural}') 39 for timepoint in timestamps.timestamps: 40 time = timestamp_snapshot_analyzer(timepoint) 41 clock_epoch_type = timepoint.clock_parameters.epoch_type 42 if clock_epoch_type == _TIME_SINCE_BOOT: 43 output.append(f' Time since boot: {time}') 44 elif clock_epoch_type == _UTC_WALL_CLOCK: 45 utc_time = time + _UTC_EPOCH 46 output.append(f' UTC time: {utc_time}') 47 else: 48 output.append(f' Time since unknown epoch {_UNKNOWN}: unknown') 49 50 return '\n'.join(output) 51 52 53def timestamp_snapshot_analyzer( 54 captured_timepoint: chrono_pb2.TimePoint, 55) -> datetime.timedelta: 56 ticks = captured_timepoint.timestamp 57 clock_period = ( 58 captured_timepoint.clock_parameters.tick_period_seconds_numerator 59 / captured_timepoint.clock_parameters.tick_period_seconds_denominator 60 ) 61 elapsed_seconds = ticks * clock_period 62 63 time_delta = datetime.timedelta(seconds=elapsed_seconds) 64 65 return time_delta 66