PcapFileEx.Timestamp (pcap_file_ex v0.5.5)
View SourceHigh-precision timestamp supporting nanosecond resolution.
Unlike Elixir's DateTime (limited to microsecond precision), this struct
preserves full nanosecond precision from PCAP files. This is essential for
accurate chronological sorting and merging of packets from multiple capture files.
Structure
A timestamp consists of two components:
secs: Unix timestamp in seconds since the epoch (January 1, 1970)nanos: Nanoseconds component (0-999,999,999)
Examples
# Create a timestamp
iex> PcapFileEx.Timestamp.new(1731065049, 735188123)
%PcapFileEx.Timestamp{secs: 1731065049, nanos: 735188123}
# Convert to total nanoseconds
iex> ts = PcapFileEx.Timestamp.new(1731065049, 735188123)
iex> PcapFileEx.Timestamp.to_unix_nanos(ts)
1731065049735188123
# Convert to DateTime (loses nanosecond precision)
iex> ts = PcapFileEx.Timestamp.new(1731065049, 735188123)
iex> PcapFileEx.Timestamp.to_datetime(ts)
~U[2024-11-08 11:24:09.735188Z]
# Compare timestamps
iex> ts1 = PcapFileEx.Timestamp.new(100, 500)
iex> ts2 = PcapFileEx.Timestamp.new(100, 600)
iex> PcapFileEx.Timestamp.compare(ts1, ts2)
:lt
# Sort packets by precise timestamp
# packets
# |> Enum.sort_by(& &1.timestamp_precise, PcapFileEx.Timestamp)Precision Note
When converting to DateTime using to_datetime/1, the nanosecond precision
is truncated to microseconds due to DateTime's limitations. The original
nanosecond precision is preserved in the Timestamp struct itself.
Summary
Functions
Compares two timestamps.
Calculates the difference between two timestamps in nanoseconds.
Creates a timestamp from an Elixir DateTime.
Creates a new timestamp from seconds and nanoseconds.
Converts a timestamp to an Elixir DateTime.
Converts a timestamp to total nanoseconds since Unix epoch.
Types
@type t() :: %PcapFileEx.Timestamp{nanos: 0..999_999_999, secs: non_neg_integer()}
Functions
Compares two timestamps.
Returns:
:ltif the first timestamp is earlier than the second:eqif the timestamps are equal:gtif the first timestamp is later than the second
Examples
iex> ts1 = PcapFileEx.Timestamp.new(100, 500)
iex> ts2 = PcapFileEx.Timestamp.new(100, 600)
iex> PcapFileEx.Timestamp.compare(ts1, ts2)
:lt
iex> ts1 = PcapFileEx.Timestamp.new(200, 500)
iex> ts2 = PcapFileEx.Timestamp.new(100, 600)
iex> PcapFileEx.Timestamp.compare(ts1, ts2)
:gt
iex> ts1 = PcapFileEx.Timestamp.new(100, 500)
iex> ts2 = PcapFileEx.Timestamp.new(100, 500)
iex> PcapFileEx.Timestamp.compare(ts1, ts2)
:eq
Calculates the difference between two timestamps in nanoseconds.
Returns a positive number if ts1 is later than ts2, negative if earlier.
Examples
iex> ts1 = PcapFileEx.Timestamp.new(100, 500)
iex> ts2 = PcapFileEx.Timestamp.new(100, 600)
iex> PcapFileEx.Timestamp.diff(ts1, ts2)
-100
iex> ts1 = PcapFileEx.Timestamp.new(101, 0)
iex> ts2 = PcapFileEx.Timestamp.new(100, 0)
iex> PcapFileEx.Timestamp.diff(ts1, ts2)
1000000000
@spec from_datetime(DateTime.t(), :microsecond | :nanosecond) :: t()
Creates a timestamp from an Elixir DateTime.
The resulting timestamp will have microsecond precision, with the nanosecond component being the microsecond value multiplied by 1000.
Parameters
datetime- The DateTime to convertresolution- Optional resolution (:microsecondor:nanosecond). Defaults to:microsecond.
Examples
iex> dt = ~U[2024-11-08 11:24:09.735188Z]
iex> PcapFileEx.Timestamp.from_datetime(dt)
%PcapFileEx.Timestamp{secs: 1731065049, nanos: 735188000}
iex> dt = ~U[2024-11-08 11:24:09.735188Z]
iex> PcapFileEx.Timestamp.from_datetime(dt, :nanosecond)
%PcapFileEx.Timestamp{secs: 1731065049, nanos: 735188000}
@spec new(non_neg_integer(), 0..999_999_999) :: t()
Creates a new timestamp from seconds and nanoseconds.
Parameters
secs- Unix timestamp in seconds since epochnanos- Nanoseconds component (0-999,999,999)
Examples
iex> PcapFileEx.Timestamp.new(1731065049, 735188123)
%PcapFileEx.Timestamp{secs: 1731065049, nanos: 735188123}
iex> PcapFileEx.Timestamp.new(0, 0)
%PcapFileEx.Timestamp{secs: 0, nanos: 0}
@spec to_datetime(t()) :: DateTime.t()
Converts a timestamp to an Elixir DateTime.
Warning: This conversion loses nanosecond precision! DateTime only supports microsecond precision (6 decimal places), so the last 3 digits of nanosecond precision are truncated.
Examples
iex> ts = PcapFileEx.Timestamp.new(1731065049, 735188123)
iex> PcapFileEx.Timestamp.to_datetime(ts)
~U[2024-11-08 11:24:09.735188Z]
# Note: 735188123 nanos becomes 735188 micros (lost 123 nanos)
@spec to_unix_nanos(t()) :: non_neg_integer()
Converts a timestamp to total nanoseconds since Unix epoch.
This is useful for precise time calculations and comparisons.
Examples
iex> ts = PcapFileEx.Timestamp.new(1731065049, 735188123)
iex> PcapFileEx.Timestamp.to_unix_nanos(ts)
1731065049735188123
iex> ts = PcapFileEx.Timestamp.new(0, 999999999)
iex> PcapFileEx.Timestamp.to_unix_nanos(ts)
999999999