From 1f23fa407fc2d5f85d767a551114621deea30bc8 Mon Sep 17 00:00:00 2001 From: JSCU-CNI <121175071+JSCU-CNI@users.noreply.github.com> Date: Thu, 27 Aug 2026 16:51:41 +0200 Subject: [PATCH 1/2] Add golang Time.time unmarshaller --- dissect/util/ts.py | 24 ++++++++++++++++++++++++ tests/test_ts.py | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/dissect/util/ts.py b/dissect/util/ts.py index 9134f03..32269a7 100644 --- a/dissect/util/ts.py +++ b/dissect/util/ts.py @@ -293,3 +293,27 @@ def dostimestamp(ts: int, centiseconds: int = 0, swap: bool = False) -> datetime seconds + extra_seconds, microseconds, ) + + +def golangtimestamp(raw: bytes) -> datetime: + """Unmarshal golang ``time.Time`` bytes to a :class:`datetime` object. + + .. code-block:: + + struct datetime { + uint8 version; // 1 or 2 + uint64 seconds; // since 01-01-0001 (Gregorian) + uint32 nanoseconds; + int16 timezone; // offset in minutes or -1 if UTC + // uint8 zone_tracker; // specific to version 2 + }; + + References: + - https://pkg.go.dev/time + """ + _version, seconds, nanoseconds, offset = struct.unpack(">BQIh", raw) + + timestamp = seconds - 62_135_596_800 + tz = timezone.utc if offset == -1 else timezone(timedelta(minutes=offset)) + dt = datetime.fromtimestamp(timestamp, tz=tz) + return dt.replace(microsecond=nanoseconds // 1000) diff --git a/tests/test_ts.py b/tests/test_ts.py index f9bcb22..8e18061 100644 --- a/tests/test_ts.py +++ b/tests/test_ts.py @@ -171,3 +171,9 @@ def test_negative_timestamps(imported_ts: ModuleType) -> None: 1969, 12, 17, 22, 59, 47, 786787, tzinfo=timezone.utc ) assert imported_ts.from_unix(-0xDEADBEEF) == datetime(1851, 8, 13, 2, 4, 1, tzinfo=timezone.utc) + + +def test_golang_timestamp(ts: ModuleType) -> None: + """Test if we can convert golang ``Time.time`` marshalled bytes to a datetime object.""" + timestamp = bytes.fromhex("010000000ee2221c201f08a2f6ffff") + assert ts.golangtimestamp(timestamp) == datetime(2026, 8, 27, 11, 53, 4, 520659, tzinfo=timezone.utc) From 656ebbecd660a3c52179844b6d0b26ab3bf3878f Mon Sep 17 00:00:00 2001 From: JSCU-CNI <121175071+JSCU-CNI@users.noreply.github.com> Date: Thu, 27 Aug 2026 17:35:12 +0200 Subject: [PATCH 2/2] Apply suggestion --- dissect/util/ts.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dissect/util/ts.py b/dissect/util/ts.py index 32269a7..0673eff 100644 --- a/dissect/util/ts.py +++ b/dissect/util/ts.py @@ -295,6 +295,9 @@ def dostimestamp(ts: int, centiseconds: int = 0, swap: bool = False) -> datetime ) +_GOTIME = struct.Struct(">BQIh") + + def golangtimestamp(raw: bytes) -> datetime: """Unmarshal golang ``time.Time`` bytes to a :class:`datetime` object. @@ -311,7 +314,7 @@ def golangtimestamp(raw: bytes) -> datetime: References: - https://pkg.go.dev/time """ - _version, seconds, nanoseconds, offset = struct.unpack(">BQIh", raw) + _version, seconds, nanoseconds, offset = _GOTIME.unpack(raw) timestamp = seconds - 62_135_596_800 tz = timezone.utc if offset == -1 else timezone(timedelta(minutes=offset))