Skip to content

Timestamp

Wraps a timezone-aware datetime.datetime, normalized to UTC.

Parameters

FieldTypeDescription
datadatetime.datetimeA timezone-aware datetime.

Raises

ExceptionCondition
TypeErrordata is not a datetime.datetime.
ValueErrordata has no tzinfo (a naive datetime).

Attributes

AttributeTypeDescription
datadatetime.datetimeThe wrapped value, converted to UTC (tzinfo=timezone.utc). Assigning a new value re-validates and re-normalizes it the same way as construction.

Methods

MethodDescription
Timestamp.coerce(value, name="value")Classmethod. Returns value unchanged if it's already a Timestamp; wraps a timezone-aware datetime.datetime. Raises TypeError otherwise.

Operators

OperationReturns
a == bbool
a != bbool
a < bbool

==/!=/< accept a Timestamp or a datetime.datetime on the right-hand side. Unlike Int/Float/String, Timestamp is not decorated with total_ordering, so <=, >, and >= are not defined — only < is. Because .data is a real datetime.datetime, arithmetic like timestamp.data - other_datetime works directly through Python's datetime API and returns a timedelta. Not hashable (__hash__ is None) — data is mutable via its setter.

Visualization

datatypes.visualize(value, entity_path=...) logs the value as an rr.TextLog, using str(data) (e.g. 2026-08-06 12:34:56.789012+00:00) rather than a numeric epoch.

Example

python
"""Demonstrates the Telekinesis Timestamp datatype."""

import time
from datetime import datetime, timezone

from loguru import logger
import rerun as rr

from telekinesis import datatypes


def timestamp_example():
    """Demonstrate creation, access, visualization, update, arithmetic, and serialization."""

    # ======================= Create ============================================
    timestamp = datatypes.Timestamp(datetime.now(timezone.utc))
    logger.info(f"Original Timestamp: {timestamp}")

    # ======================= Inspect ===========================================
    data = timestamp.data
    logger.info(f"Underlying Timestamp data: {data}")

    # ======================= Visualize =========================================
    rr.init("timestamp_example", spawn=True)
    datatypes.visualize(timestamp, entity_path="/Timestamp/my_timestamp")

    # ======================= Update ============================================
    timestamp.data = datetime.now(timezone.utc)
    logger.info(f"Updated Timestamp: {timestamp}")
    datatypes.visualize(timestamp, entity_path="/Timestamp/updated", label="Updated Timestamp")

    # ======================= Arithmetic ========================================
    diff = timestamp.data - data
    logger.info(f"Time difference between original and updated timestamp: {diff}")

    # ======================= Serialize / Deserialize ===========================
    start = time.perf_counter()
    serialized = datatypes.serialize(timestamp)
    serialization_ms = (time.perf_counter() - start) * 1000

    start = time.perf_counter()
    deserialized = datatypes.deserialize(serialized)["param_0"]
    deserialization_ms = (time.perf_counter() - start) * 1000

    logger.info(f"Deserialized Timestamp: {deserialized}")
    logger.info(f"Round-trip successful: {timestamp == deserialized}")
    logger.info(f"Serialization time: {serialization_ms:.3f} ms")
    logger.info(f"Deserialization time: {deserialization_ms:.3f} ms")


if __name__ == "__main__":
    timestamp_example()