diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c524071..71b1598 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,10 @@ Changelog ========= +* Add support for ``datetime.timedelta`` to ``time_machine.travel()``. + + Thanks to Nate Dudenhoeffer in `PR #298 `__. + * Add ``shift()`` method to the ``time_machine`` pytest fixture. Thanks to Stefaan Lippens in `PR #312 `__. diff --git a/README.rst b/README.rst index 755325c..88db11f 100644 --- a/README.rst +++ b/README.rst @@ -77,6 +77,9 @@ It may be: If it has ``tzinfo`` set to a |zoneinfo-instance|_, the current timezone will also be mocked. * A ``datetime.date``. This will be converted to a UTC datetime with the time 00:00:00. +* A ``datetime.timedelta``. + This will be interpreted relative to the current time. + If already within a ``travel()`` block, the ``shift()`` method is easier to use (documented below). * A ``float`` or ``int`` specifying a `Unix timestamp `__ * A string, which will be parsed with `dateutil.parse `__ and converted to a timestamp. Again, if the result is naive, it will be assumed to have the UTC time zone. diff --git a/src/time_machine/__init__.py b/src/time_machine/__init__.py index c0d6bda..4fa2142 100644 --- a/src/time_machine/__init__.py +++ b/src/time_machine/__init__.py @@ -84,6 +84,7 @@ int, float, dt.datetime, + dt.timedelta, dt.date, str, ] @@ -124,6 +125,8 @@ def extract_timestamp_tzname( if dest.tzinfo is None: dest = dest.replace(tzinfo=dt.timezone.utc) timestamp = dest.timestamp() + elif isinstance(dest, dt.timedelta): + timestamp = time() + dest.total_seconds() elif isinstance(dest, dt.date): timestamp = dt.datetime.combine( dest, dt.time(0, 0), tzinfo=dt.timezone.utc diff --git a/tests/test_time_machine.py b/tests/test_time_machine.py index 9736be4..0f086bf 100644 --- a/tests/test_time_machine.py +++ b/tests/test_time_machine.py @@ -444,6 +444,24 @@ def test_destination_date(): assert time.time() == EPOCH +def test_destination_timedelta(): + now = time.time() + with time_machine.travel(dt.timedelta(seconds=3600)): + assert now + 3600 <= time.time() <= now + 3601 + + +def test_destination_timedelta_negative(): + now = time.time() + with time_machine.travel(dt.timedelta(seconds=-3600)): + assert now - 3600 <= time.time() <= now - 3599 + + +def test_destination_timedelta_nested(): + with time_machine.travel(EPOCH): + with time_machine.travel(dt.timedelta(seconds=10)): + assert time.time() == EPOCH + 10.0 + + @time_machine.travel("1970-01-01 00:01 +0000") def test_destination_string(): assert time.time() == EPOCH + 60.0