time-machine

raw JSON →
3.2.0 verified Tue May 12 auth: no python install: verified

time-machine is a Python library that enables 'time travel' in your tests by mocking Python's standard library functions that return the current date or datetime. It achieves this efficiently using C extensions, providing a fast and robust solution for time-dependent testing. The library is actively maintained, with version 3.2.0 released in December 2025.

pip install time-machine
error error: command 'gcc' failed with exit status 1
cause The C extension for `time-machine` failed to compile during installation, often due to missing build tools or Python development headers.
fix
Ensure development tools and Python development headers are installed for your operating system (e.g., sudo apt-get install build-essential python3-dev on Debian/Ubuntu, or Xcode command line tools on macOS).
error import time-machine
cause Python module names cannot contain hyphens; the library's Python package name uses an underscore.
fix
Use import time_machine instead.
error TypeError: travel() missing 1 required positional argument: 'destination'
cause The `time_machine.travel()` function requires a `destination` argument, which specifies the point in time to travel to.
fix
Provide a valid destination like a datetime string, a datetime object, date object, or a float timestamp, e.g., time_machine.travel('2023-01-01').
error TypeError: Expected str, datetime.datetime, datetime.date, or float, got NoneType
cause The `destination` argument provided to `time_machine.travel()` was of an unsupported type (e.g., `None`), instead of a string, `datetime`, `date`, or float.
fix
Ensure the destination argument is one of the supported types, for example, '2024-01-01 10:00:00' or datetime.datetime(2024, 1, 1, 10, 0, 0).
error ValueError: Invalid destination: "invalid-date-string"
cause The string provided as the `destination` argument to `time_machine.travel()` could not be parsed into a valid date or datetime.
fix
Provide a valid, unambiguous date or datetime string, such as 'YYYY-MM-DD', 'YYYY-MM-DD HH:MM:SS', or an ISO 8601 formatted string.
gotcha Time is a global state. When mocking time with `time-machine`, all concurrent threads or asynchronous functions within the same process will also be affected. This can lead to unexpected behavior if not accounted for.
fix Be aware of the global nature of time mocking in multithreaded or asynchronous tests. Design tests to isolate time-sensitive operations or use careful synchronization.
gotcha `time-machine` only mocks Python's standard library functions for time. It does not affect other processes (e.g., database servers, external APIs) or libraries that make direct C-level system calls for time.
fix For external systems, mock the external system's responses directly rather than relying on `time-machine`.
gotcha `time-machine` currently only works with CPython (the standard Python interpreter) and is not compatible with other Python interpreters like PyPy.
fix Ensure your testing environment uses CPython if `time-machine` is a dependency.
breaking As of version 3.0.0, `time-machine` no longer mocks `time.monotonic()` and `time.monotonic_ns()`. Mocking these functions caused significant issues with asyncio event loops, test duration measurements, and other libraries relying on a strictly monotonic clock.
fix If you need to mock `time.monotonic()` or `time.monotonic_ns()`, use `unittest.mock` or a similar patching mechanism manually, but be aware of potential side effects.
breaking The `tz_offset` argument for specifying timezones was removed in version 2.0.0. Timezones should now be specified by providing a `datetime` object with a `zoneinfo.ZoneInfo` instance attached (Python 3.9+ or `backports.zoneinfo`).
fix Update `time_machine.travel` calls to pass a timezone-aware `datetime` object (e.g., `dt.datetime(..., tzinfo=ZoneInfo('America/Los_Angeles'))`) instead of `tz_offset`.
gotcha The default `naive_mode` for interpreting naive datetimes is `MIXED`, which can be confusing (naive `datetime` objects are UTC, strings are local). It's recommended to explicitly set `naive_mode` to `LOCAL` or `ERROR` for consistent and clearer behavior.
fix Set `time_machine.naive_mode = time_machine.LOCAL` or `time_machine.naive_mode = time_machine.ERROR` in your test setup to enforce a consistent interpretation.
gotcha Attempting to start time travel with `time-machine` when `freezegun` (another time-mocking library) is already active will raise a `RuntimeError` to prevent conflicts and ensure a clean state for mocking.
fix Ensure that `freezegun` is not active in the same process where `time-machine` is being used. If migrating, use the provided `time_machine migrate` CLI tool.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.15s 17.9M
3.10 alpine (musl) - - 0.15s 17.9M
3.10 slim (glibc) wheel 1.7s 0.09s 18M
3.10 slim (glibc) - - 0.09s 18M
3.11 alpine (musl) wheel - 0.20s 19.8M
3.11 alpine (musl) - - 0.22s 19.8M
3.11 slim (glibc) wheel 1.7s 0.19s 20M
3.11 slim (glibc) - - 0.15s 20M
3.12 alpine (musl) wheel - 0.20s 11.6M
3.12 alpine (musl) - - 0.21s 11.6M
3.12 slim (glibc) wheel 1.5s 0.18s 12M
3.12 slim (glibc) - - 0.18s 12M
3.13 alpine (musl) wheel - 0.21s 11.4M
3.13 alpine (musl) - - 0.20s 11.3M
3.13 slim (glibc) wheel 1.5s 0.17s 12M
3.13 slim (glibc) - - 0.18s 12M
3.9 alpine (musl) wheel - 0.24s 18.3M
3.9 alpine (musl) - - 0.27s 18.3M
3.9 slim (glibc) wheel 2.1s 0.22s 19M
3.9 slim (glibc) - - 0.20s 19M

Demonstrates `time-machine` as a decorator and context manager to fix the current time for testing.

import datetime as dt
import time_machine

@time_machine.travel("1955-11-05 01:22")
def test_delorean():
    assert dt.date.today().isoformat() == "1955-11-05"

def use_context_manager():
    with time_machine.travel(dt.datetime(1985, 10, 26, 1, 24, tzinfo=dt.timezone.utc)):
        assert dt.datetime.now(dt.timezone.utc).year == 1985

# To run the example (in a test framework like pytest, this would be automatic):
if __name__ == "__main__":
    test_delorean()
    use_context_manager()
    print("Quickstart example ran successfully!")