{"id":22927066,"url":"https://github.com/beste/clock","last_synced_at":"2025-04-07T14:15:42.131Z","repository":{"id":41985354,"uuid":"346936233","full_name":"beste/clock","owner":"beste","description":"⏱ A collection of Clock implementations.","archived":false,"fork":false,"pushed_at":"2024-04-24T18:56:38.000Z","size":65,"stargazers_count":54,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"3.x","last_synced_at":"2024-04-24T20:23:32.889Z","etag":null,"topics":["beste","clock","php","psr-20"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beste.png","metadata":{"funding":{"github":"jeromegamez"},"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-12T04:24:06.000Z","updated_at":"2024-06-18T18:21:46.141Z","dependencies_parsed_at":"2024-04-24T19:59:53.250Z","dependency_job_id":"fe0a44c3-cdba-4bea-8e41-71e7f404f8c6","html_url":"https://github.com/beste/clock","commit_stats":{"total_commits":18,"total_committers":3,"mean_commits":6.0,"dds":0.2222222222222222,"last_synced_commit":"fdf9c1bd04606678218b6baa1f060a130fb1be85"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beste%2Fclock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beste%2Fclock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beste%2Fclock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beste%2Fclock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beste","download_url":"https://codeload.github.com/beste/clock/tar.gz/refs/heads/3.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247666015,"owners_count":20975788,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beste","clock","php","psr-20"],"created_at":"2024-12-14T09:13:00.520Z","updated_at":"2025-04-07T14:15:42.107Z","avatar_url":"https://github.com/beste.png","language":"PHP","funding_links":["https://github.com/sponsors/jeromegamez"],"categories":[],"sub_categories":[],"readme":"# Clock\n\n[![Current version](https://img.shields.io/packagist/v/beste/clock.svg?logo=composer)](https://packagist.org/packages/beste/clock)\n[![Packagist PHP Version Support](https://img.shields.io/packagist/php-v/beste/clock)](https://packagist.org/packages/beste/clock)\n[![Tests](https://github.com/beste/clock/actions/workflows/tests.yml/badge.svg)](https://github.com/beste/clock/actions/workflows/tests.yml)\n\nA collection of [PSR-20](https://www.php-fig.org/psr/psr-20/) Clock implementations.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Clocks](#clocks)\n    - [`SystemClock`](#systemclock) - Time, as your computer (k)nows it\n    - [`LocalizedClock`](#localizedclock) - A clock in a(nother) time zone\n    - [`UTCClock`](#utcclock) - The clock that you should™ use\n    - [`FrozenClock`](#frozenclock) - A clock that stopped moving (perfect for tests)\n    - [`MinuteClock`](#minuteclock) - Who cares about seconds or even less?\n    - [`WrappingClock`](#wrappingclock) - Allows wrapping a non-clock with a `now()` method in a clock\n- [Running Tests](#running-tests)\n    \n## Installation\n\n```shell\ncomposer require beste/clock\n```\n\n## Clocks\n\n### `SystemClock`\n\nA System Clock will return a time just as if you would use `new DateTimeImmutable()`. The time zone of the returned\nvalue is determined by the clock's environment, for example by the time zone that has been configured in your\napplication, by a previously used `date_default_timezone_set()` or by the value of `date.timezone` in the\n`php.ini`. If none of these are explicitly set, it uses the `UTC` timezone.\n\n```php\n# examples/system_clock.php\n\nuse Beste\\Clock\\SystemClock;\n\n$clock = SystemClock::create();\n\nprintf(\"On your system, the current date and time is %s\\n\", $clock-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\n\ndate_default_timezone_set('America/Los_Angeles');\n\nprintf(\"Now it's %s\\n\", $clock-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\n\ndate_default_timezone_set('Europe/Berlin');\n\nprintf(\"Now it's %s\\n\", $clock-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\n```\n\n### `LocalizedClock`\n\nA localized clock is aware of the time zone in which it is located. While the time zone of the `SystemClock` is\ndetermined from the environment (your PHP configuration), this clock uses the time zone that you initialize it with.\n\n```php\n# examples/localized_clock.php\n\nuse Beste\\Clock\\LocalizedClock;\n\n$berlin = LocalizedClock::in('Europe/Berlin');\n$denver = LocalizedClock::in(new DateTimeZone('America/Denver'));\n\nprintf(\"Berlin: %s\\n\", $berlin-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\nprintf(\"Denver: %s\\n\", $denver-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\n```\n\n### `UTCClock`\n\n`UTC` is the abbreviation for [Coordinated Universal Time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time)\nand a special kind of time zone that is not affected by daylight saving time. It is commonly used for the communication\nof time across different systems (e.g. between your PHP application and a database, or between a backend\nand a frontend). An `UTCClock` instance behaves exactly the same as an instance of `LocalizedClock::in('UTC')`.\n\n```php\n# examples/utc_clock.php\n\nuse Beste\\Clock\\UTCClock;\n\n$clock = UTCClock::create();\n\n$anotherTimeZone = 'Africa/Casablanca';\n\ndate_default_timezone_set($anotherTimeZone);\n\nprintf(\"The system time zone is %s.\\n\", $anotherTimeZone);\nprintf(\"The clock's time zone is %s.\\n\", $clock-\u003enow()-\u003egetTimezone()-\u003egetName());\n```\n\n### `FrozenClock`\n\nA frozen clock doesn't move - the time we set it with will stay the same... unless we change it. That makes the\nfrozen clock perfect for testing the behaviour of your time-based use cases, for example in Unit Tests.\n\n```php\n# examples/frozen_clock.php\n\nuse Beste\\Clock\\FrozenClock;\nuse Beste\\Clock\\SystemClock;\n\n$frozenClock = FrozenClock::withNowFrom(SystemClock::create());\n\nprintf(\"\\nThe clock is frozen at %s\", $frozenClock-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\nprintf(\"\\nLet's wait a second…\");\nsleep(1);\nprintf(\"\\nIt's one second later, but the clock is still frozen at %s\", $frozenClock-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\n\n$frozenClock-\u003esetTo($frozenClock-\u003enow()-\u003emodify('-5 minutes'));\nprintf(\"\\nAfter turning back the clock 5 minutes, it's %s\", $frozenClock-\u003enow()-\u003eformat('Y-m-d H:i:s T (P)'));\n```\n\n### `MinuteClock`\n\nIn some cases, microseconds, milliseconds, or even seconds are too precise for some use cases - sometimes it's just\nenough if something happened in the same minute. Using the minute\n\n```php\n# examples/minute_clock.php\n\nuse Beste\\Clock\\FrozenClock;\nuse Beste\\Clock\\MinuteClock;\n\n$frozenClock = FrozenClock::at(new DateTimeImmutable('01:23:45'));\n$clock = MinuteClock::wrapping($frozenClock);\n\nprintf(\"For %s, the minute clock returns %s\\n\",\n    $frozenClock-\u003enow()-\u003eformat('H:i:s'),\n    $clock-\u003enow()-\u003eformat('H:i:s')\n);\n\n$frozenClock-\u003esetTo($frozenClock-\u003enow()-\u003emodify('+10 seconds')); // 01:23:55\n\nprintf(\"For %s, the minute clock still returns %s\\n\",\n    $frozenClock-\u003enow()-\u003eformat('H:i:s'),\n    $clock-\u003enow()-\u003eformat('H:i:s')\n);\n```\n\n### `WrappingClock`\n\nIf you already have an object with a `now()` method returning a `DateTimeImmutable` object, you can wrap it \nin a `WrappingClock` to make it a \"real\" Clock.\n\nas a \"real\" clock.\n\n```php\n# examples/wrapping_clock.php\n\nuse Beste\\Clock\\WrappingClock;\n\n// Create a frozen $now so that we can test the wrapping clock.\n$now = new DateTimeImmutable('2012-04-24 12:00:00');\n\n// Create an object that is NOT a clock, but has a now() method returning the frozen $now.\n$clock = new class($now) {\n    private \\DateTimeImmutable $now;\n\n    public function __construct(\\DateTimeImmutable $now)\n    {\n        $this-\u003enow = $now;\n    }\n\n    public function now(): \\DateTimeImmutable\n    {\n        return $this-\u003enow;\n    }\n};\n\n// We can now wrap the object in a clock.\n$wrappedClock = WrappingClock::wrapping($clock);\n\nassert($now-\u003eformat(DATE_ATOM) === $wrappedClock-\u003enow()-\u003eformat(DATE_ATOM));\n```\n\n## Running tests\n\n```shell\ncomposer test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeste%2Fclock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeste%2Fclock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeste%2Fclock/lists"}