colopl / colopl_timeshifter
Current time modification PHP extension.
Package info
github.com/colopl/php-colopl_timeshifter
Type:php-ext
Ext name:ext-colopl_timeshifter
pkg:composer/colopl/colopl_timeshifter
Requires
- php: ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.1 || ~8.5.0
Requires (Dev)
- phpstan/phpstan: ^2.1.32
- phpstan/phpstan-phpunit: ^2.0.8
- phpunit/phpunit: ^10 || ^11 || ^12.4.5 || ^13.0.0
Provides
This package is auto-updated.
Last update: 2026-06-22 03:23:15 UTC
README
This extension changes the current time in PHP to a specified modified value.
Warning
DO NOT USE THIS EXTENSION IN ANY PRODUCTION ENVIRONMENT!!!
At present, this extension is effective for the following functions:
- Any built-in PHP processing that handles the current time (
ext-date,ext-calendar) NOW()and many statements in MySQL or compatible DBMS via PDO- Server environment variables for request time (e.g.
$_SERVER['REQUEST_TIME'])
Install
Clone the repository with submodules and build the extension.
$ git clone --recursive "https://github.com/colopl/php-colopl_timeshifter.git" "colopl_timeshifter" $ cd "colopl_timeshifter/ext" $ phpize $ ./configure --with-php-config="$(which php-config)" $ make -j"$(nproc)" $ TEST_PHP_ARGS="--show-diff -q" make test $ sudo make install
Enable the extension after installation.
$ echo "extension=colopl_timeshifter" | sudo tee "$(php-config --ini-dir)/99-colopl_timeshifter.ini" $ php -m | grep "colopl_timeshifter" colopl_timeshifter
Build Ubuntu packages
Ubuntu packages are built with standard Debian packaging via dpkg-buildpackage, not checkinstall.
The packaging definitions live alongside each build target under build/*/debian.
Build packages for the official Ubuntu 22.04 PHP 8.1 stack:
$ docker build -f "build/ubuntu2204/Dockerfile" -t "colopl-timeshifter-u2204-php81" . $ mkdir -p "artifacts" $ docker run --rm -e VERSION="x.y.z" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-timeshifter-u2204-php81"
This target produces php8.1-colopl-timeshifter_x.y.z_<arch>_ubuntu22.04_default.deb.
Build packages for Ubuntu 22.04 with the Ondrej Sury PHP 8.4 repository:
$ docker build -f "build/ubuntu2204_sury84/Dockerfile" -t "colopl-timeshifter-u2204-sury84-php84" . $ mkdir -p "artifacts" $ docker run --rm -e VERSION="x.y.z" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-timeshifter-u2204-sury84-php84"
This target produces php8.4-colopl-timeshifter_x.y.z_<arch>_ubuntu22.04_sury.deb.
Build packages for the official Ubuntu 26.04 PHP 8.5 stack:
$ docker build -f "build/ubuntu2604/Dockerfile" -t "colopl-timeshifter-u2604-php85" . $ mkdir -p "artifacts" $ docker run --rm -e VERSION="x.y.z" -v "$(pwd)/artifacts:/tmp/artifacts" "colopl-timeshifter-u2604-php85"
This target produces php8.5-colopl-timeshifter_x.y.z_<arch>_ubuntu26.04_default.deb.
Generated .ddeb, .changes, and .buildinfo artifacts use the same Ubuntu version and PHP variant suffix when present.
Migration Guide
From Composer Package to Packagist PHP Extension Installer
As of version 2.0, this package is distributed as a PHP extension via the Packagist PHP Extension installer (PIE), not as a Composer library package. The former PHP wrapper interface (Colopl\ColoplTimeShifter\Manager) is now implemented by the extension itself.
For users previously using Manager class
Before (version < 2.0):
<?php require 'vendor/autoload.php'; use Colopl\ColoplTimeShifter\Manager; // Shift the current time to 2021-01-01 00:00:00 UTC. Manager::hookDateTime(new DateTimeImmutable('2021-01-01 00:00:00 UTC')); echo date('Y-m-d H:i:s'); echo time(); Manager::unhook();
After (version >= 2.0):
-
Install the extension via the package manager (Ubuntu example):
apt-get install php-colopl-timeshifter
Or via Packagist PHP Extension installer:
composer require --dev-only colopl/colopl_timeshifter --with-php-extensions
-
Verify the extension is loaded:
php -m | grep colopl_timeshifter -
Use the extension-provided
Managerclass from your test code:<?php use Colopl\ColoplTimeShifter\Manager; // Shift the current time to 2021-01-01 00:00:00 UTC. Manager::hookDateTime(new DateTimeImmutable('2021-01-01 00:00:00 UTC')); echo date('Y-m-d H:i:s'); echo time(); Manager::unhook();
Key differences:
- No Composer autoloaded wrapper: The
Colopl\ColoplTimeShifter\Managerclass is provided by the loaded extension. - Compatibility API: Existing calls to
Manager::hookDateTime(),Manager::hookDateInterval(),Manager::unhook(),Manager::isHooked(), andManager::isAvailable()continue to work after the extension is installed. - Direct functions remain available: You can still call
register_hook($interval),unregister_hook(), andis_hooked()directly when you want the lower-level API. - Global hook state: Once registered, time shifting applies to hooked time-related functions until
unregister_hook()is called or the request ends withcolopl_timeshifter.is_restore_per_request=1.
INI directives
colopl_timeshifter.is_hook_pdo_mysql
Type: bool
Default: true
Run-time switchable: No (PHP_INI_SYSTEM)
Enables or disables the hook into \PDO::__construct to swap the current time in MySQL function and keywords such as NOW() and CURRENT_TIMESTAMP.
colopl_timeshifter.is_hook_request_time
Type: bool
Default: true
Run-time switchable: No (PHP_INI_SYSTEM)
Selects whether to hook the $_SERVER superglobals REQUEST_TIME and REQUEST_TIME_FLOAT.
colopl_timeshifter.is_restore_per_request
Type: bool
Default: false
Run-time switchable: Yes (PHP_INI_ALL)
Sets whether or not to unhook at the end of the request.
Classes
Tip
The extension provides both the compatibility Manager class and the lower-level functions below.
\Colopl\ColoplTimeShifter\Manager::isAvailable(): bool
Checks whether TimeShifter is available. When this class is provided by the extension, it returns true.
\Colopl\ColoplTimeShifter\Manager::isHooked(): bool
Checks whether the hook is active.
\Colopl\ColoplTimeShifter\Manager::unhook(): bool
Breaks the hook and returns true.
\Colopl\ColoplTimeShifter\Manager::hookDateTime(\DateTimeInterface $dateTime): bool
Sets the current time to the specified date and time.
\Colopl\ColoplTimeShifter\Manager::hookDateInterval(\DateInterval $dateInterval): bool
Sets the time difference to be subtracted from the current time.
Functions
\Colopl\ColoplTimeShifter\register_hook(\DateInterval $interval): bool
Sets the time difference to be subtracted from the current time.
If the hook succeeds, it returns true; otherwise, it returns false.
\Colopl\ColoplTimeShifter\unregister_hook(): void
Breaks the hook.
\Colopl\ColoplTimeShifter\is_hooked(): bool
Checks whether the hook is active. Returns true if the hook is active, false otherwise.
License
BSD-3-Clause