Bug Report
Description
The TryFrom implementations for TimestampMicro and TimestampNano both use incorrect
divisors when converting to Unix seconds before passing to chrono::DateTime::from_timestamp.
Sub-second precision is also silently discarded by passing 0 as the nanoseconds argument.
| Type |
Current divisor |
Correct divisor |
Result |
TimestampMicro |
/ 1_000 (→ milliseconds) |
/ 1_000_000 (→ seconds) |
1,000× too large |
TimestampNano |
/ 1_000_000 (→ milliseconds) |
/ 1_000_000_000 (→ seconds) |
1,000× too large |
Affected Code
timeflow/src/datetime.rs:
// TimestampMicro (~line 448)
chrono::DateTime::from_timestamp(*timestamp / 1_000, 0)
// ^^^^^ should be / 1_000_000
// TimestampNano (~line 464)
chrono::DateTime::from_timestamp(*timestamp / 1_000_000, 0)
// ^^^^^^^^^ should be / 1_000_000_000
Reproduction
use timeflow::prelude::*;
use timeflow::timestamp::{TimestampMicro, TimestampNano};
// Real microsecond epoch for 2024-12-31 22:10:10
let ts_micro = TimestampMicro::from(1_735_683_010_000_000);
let dt = DateTime::try_from(ts_micro);
// Expected: Ok("2024-12-31 22:10:10")
// Actual: Err(ParseFromTimestamp(...))
// Real nanosecond epoch for 2024-12-31 22:10:10
let ts_nano = TimestampNano::from(1_735_683_010_000_000_000);
let dt = DateTime::try_from(ts_nano);
// Expected: Ok("2024-12-31 22:10:10")
// Actual: Err(ParseFromTimestamp(...))
Why the existing tests don't catch this
All three test inputs are orders of magnitude smaller than real timestamps in their
advertised units. After dividing by the (wrong) current divisor, they happen to produce
a valid seconds-epoch value for the expected date. Example for TimestampMicro:
1_735_683_010_000 / 1_000 = 1_735_683_010 — a valid seconds value — but
1_735_683_010_000 is itself not a real microsecond timestamp for that date
(it would be 1_735_683_010_000_000).
Fix
// TimestampMicro
chrono::DateTime::from_timestamp(*timestamp / 1_000_000, 0)
// TimestampNano
chrono::DateTime::from_timestamp(*timestamp / 1_000_000_000, 0)
To also preserve sub-second precision, prefer the dedicated chrono APIs:
// TimestampMicro
chrono::DateTime::from_timestamp_micros(*timestamp)
// TimestampNano
chrono::DateTime::from_timestamp_nanos(*timestamp) // returns DateTime directly, no Option
Severity
High — all callers supplying genuine micro- or nanosecond timestamps receive a runtime
error or a silently wrong date. Tests must also be updated to use real-scale values.
Bug Report
Description
The
TryFromimplementations forTimestampMicroandTimestampNanoboth use incorrectdivisors when converting to Unix seconds before passing to
chrono::DateTime::from_timestamp.Sub-second precision is also silently discarded by passing
0as the nanoseconds argument.TimestampMicro/ 1_000(→ milliseconds)/ 1_000_000(→ seconds)TimestampNano/ 1_000_000(→ milliseconds)/ 1_000_000_000(→ seconds)Affected Code
timeflow/src/datetime.rs:Reproduction
Why the existing tests don't catch this
All three test inputs are orders of magnitude smaller than real timestamps in their
advertised units. After dividing by the (wrong) current divisor, they happen to produce
a valid seconds-epoch value for the expected date. Example for TimestampMicro:
1_735_683_010_000 / 1_000 = 1_735_683_010 — a valid seconds value — but
1_735_683_010_000 is itself not a real microsecond timestamp for that date
(it would be 1_735_683_010_000_000).
Fix
Severity
High — all callers supplying genuine micro- or nanosecond timestamps receive a runtime
error or a silently wrong date. Tests must also be updated to use real-scale values.