diff --git a/prometheus_client/samples.py b/prometheus_client/samples.py index 994d1281..6eac7d64 100644 --- a/prometheus_client/samples.py +++ b/prometheus_client/samples.py @@ -13,7 +13,8 @@ def __init__(self, sec: float, nsec: float) -> None: self.nsec: int = int(nsec) def __str__(self) -> str: - return f"{self.sec}.{self.nsec:09d}" + sign = '-' if self.sec < 0 or self.nsec < 0 else '' + return f"{sign}{abs(self.sec)}.{abs(self.nsec):09d}" def __repr__(self) -> str: return f"Timestamp({self.sec}, {self.nsec})" diff --git a/tests/openmetrics/test_exposition.py b/tests/openmetrics/test_exposition.py index 3ba4031a..5abc0423 100644 --- a/tests/openmetrics/test_exposition.py +++ b/tests/openmetrics/test_exposition.py @@ -492,6 +492,8 @@ def collect(self): metric.add_sample("ts", {"foo": "d"}, 0, Timestamp(123, 456000000)) metric.add_sample("ts", {"foo": "e"}, 0, Timestamp(123, 456000)) metric.add_sample("ts", {"foo": "f"}, 0, Timestamp(123, 456)) + metric.add_sample("ts", {"foo": "g"}, 0, Timestamp(-123, 456000000)) + metric.add_sample("ts", {"foo": "h"}, 0, Timestamp(-123, 456)) yield metric self.registry.register(MyCollector()) @@ -503,6 +505,8 @@ def collect(self): ts{foo="d"} 0.0 123.456000000 ts{foo="e"} 0.0 123.000456000 ts{foo="f"} 0.0 123.000000456 +ts{foo="g"} 0.0 -123.456000000 +ts{foo="h"} 0.0 -123.000000456 # EOF """, generate_latest(self.registry, version="1.0.0")) diff --git a/tests/test_samples.py b/tests/test_samples.py index 7b59218b..e1e416da 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -4,6 +4,23 @@ class TestSamples(unittest.TestCase): + def test_negative_timestamp_string(self): + for nsec, expected in [ + (0, '-123.000000000'), + (1, '-123.000000001'), + (456000000, '-123.456000000'), + (999999999, '-123.999999999'), + ]: + with self.subTest(nsec=nsec): + timestamp = samples.Timestamp(-123, nsec) + self.assertEqual(str(timestamp), expected) + self.assertEqual(float(str(timestamp)), float(timestamp)) + + def test_negative_timestamp_string_with_zero_seconds(self): + timestamp = samples.Timestamp(-0.5, 500000000) + self.assertEqual(str(timestamp), '-0.500000000') + self.assertEqual(float(str(timestamp)), float(timestamp)) + def test_gt(self): self.assertEqual(samples.Timestamp(1, 1) > samples.Timestamp(1, 1), False) self.assertEqual(samples.Timestamp(1, 1) > samples.Timestamp(1, 2), False)