{"id":961,"library":"time-machine","title":"time-machine","description":"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.","status":"active","version":"3.2.0","language":"python","source_language":"en","source_url":"https://github.com/adamchainz/time-machine","tags":["testing","time","mock","datetime","pytest"],"install":[{"cmd":"pip install time-machine","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Required for `zoneinfo.ZoneInfo` support on Python versions older than 3.9 when mocking timezones.","package":"backports.zoneinfo","optional":true},{"reason":"Needed for parsing string destinations (e.g., 'YYYY-MM-DD') if not providing explicit datetime objects.","package":"python-dateutil","optional":true}],"imports":[{"symbol":"travel","correct":"from time_machine import travel"},{"symbol":"is_travelling","correct":"from time_machine import is_travelling"},{"symbol":"naive_mode","correct":"from time_machine import naive_mode"}],"quickstart":{"code":"import datetime as dt\nimport time_machine\n\n@time_machine.travel(\"1955-11-05 01:22\")\ndef test_delorean():\n    assert dt.date.today().isoformat() == \"1955-11-05\"\n\ndef use_context_manager():\n    with time_machine.travel(dt.datetime(1985, 10, 26, 1, 24, tzinfo=dt.timezone.utc)):\n        assert dt.datetime.now(dt.timezone.utc).year == 1985\n\n# To run the example (in a test framework like pytest, this would be automatic):\nif __name__ == \"__main__\":\n    test_delorean()\n    use_context_manager()\n    print(\"Quickstart example ran successfully!\")","lang":"python","description":"Demonstrates `time-machine` as a decorator and context manager to fix the current time for testing."},"warnings":[{"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.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For external systems, mock the external system's responses directly rather than relying on `time-machine`.","message":"`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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure your testing environment uses CPython if `time-machine` is a dependency.","message":"`time-machine` currently only works with CPython (the standard Python interpreter) and is not compatible with other Python interpreters like PyPy.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"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.","severity":"breaking","affected_versions":">=3.0.0"},{"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`.","message":"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`).","severity":"breaking","affected_versions":">=2.0.0"},{"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.","message":"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.","severity":"gotcha","affected_versions":"All versions"},{"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.","message":"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.","severity":"gotcha","affected_versions":">=3.2.0"}],"env_vars":null,"last_verified":"2026-05-12T21:45:15.414Z","next_check":"2026-06-27T00:00:00.000Z","problems":[{"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).","cause":"The C extension for `time-machine` failed to compile during installation, often due to missing build tools or Python development headers.","error":"error: command 'gcc' failed with exit status 1"},{"fix":"Use `import time_machine` instead.","cause":"Python module names cannot contain hyphens; the library's Python package name uses an underscore.","error":"import time-machine"},{"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')`.","cause":"The `time_machine.travel()` function requires a `destination` argument, which specifies the point in time to travel to.","error":"TypeError: travel() missing 1 required positional argument: 'destination'"},{"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)`.","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.","error":"TypeError: Expected str, datetime.datetime, datetime.date, or float, got NoneType"},{"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.","cause":"The string provided as the `destination` argument to `time_machine.travel()` could not be parsed into a valid date or datetime.","error":"ValueError: Invalid destination: \"invalid-date-string\""}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":null,"quickstart_tag":null,"pypi_latest":"3.2.0","cli_name":"","install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.8,"disk_size":"17.9M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.8,"disk_size":"17.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.09,"mem_mb":4.8,"disk_size":"18M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":4.8,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":4.9,"disk_size":"19.8M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.22,"mem_mb":4.9,"disk_size":"19.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.19,"mem_mb":4.9,"disk_size":"20M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":4.9,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":5,"disk_size":"11.6M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":5,"disk_size":"11.6M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.18,"mem_mb":5,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":5,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":5.1,"disk_size":"11.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":5.1,"disk_size":"11.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.17,"mem_mb":4.9,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":4.9,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.24,"mem_mb":7.7,"disk_size":"18.3M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.27,"mem_mb":7.7,"disk_size":"18.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":2.1,"import_time_s":0.22,"mem_mb":7.7,"disk_size":"19M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.2,"mem_mb":7.7,"disk_size":"19M"}]},"quickstart_checks":{"last_tested":"2026-04-24","tag":null,"tag_description":null,"results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}