{"id":23434927,"url":"https://github.com/gpslab/interval","last_synced_at":"2025-04-13T03:19:44.232Z","repository":{"id":13833730,"uuid":"75078831","full_name":"gpslab/interval","owner":"gpslab","description":"Interval Value Objects","archived":false,"fork":false,"pushed_at":"2022-03-16T13:15:23.000Z","size":199,"stargazers_count":6,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-26T20:21:16.903Z","etag":null,"topics":["datetime","ddd","doctrine","interval","ip","ipv4","ipv4-network","ipv6","ipv6-network","period","php","value-object"],"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/gpslab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-29T12:21:31.000Z","updated_at":"2022-04-05T22:03:51.000Z","dependencies_parsed_at":"2022-08-07T07:15:47.484Z","dependency_job_id":null,"html_url":"https://github.com/gpslab/interval","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpslab%2Finterval","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpslab%2Finterval/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpslab%2Finterval/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gpslab%2Finterval/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gpslab","download_url":"https://codeload.github.com/gpslab/interval/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248658220,"owners_count":21140899,"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":["datetime","ddd","doctrine","interval","ip","ipv4","ipv4-network","ipv6","ipv6-network","period","php","value-object"],"created_at":"2024-12-23T12:34:03.416Z","updated_at":"2025-04-13T03:19:44.211Z","avatar_url":"https://github.com/gpslab.png","language":"PHP","readme":"[![GitHub Actions](https://github.com/gpslab/interval/workflows/CI/badge.svg)](https://github.com/gpslab/interval/actions?query=workflow%3A%22CI%22+branch%3Amaster)\n[![Latest Stable Version](https://img.shields.io/packagist/v/gpslab/interval.svg?maxAge=3600\u0026label=stable)](https://packagist.org/packages/gpslab/interval)\n[![Code Coverage](https://codecov.io/gh/gpslab/interval/branch/master/graph/badge.svg)](https://codecov.io/gh/gpslab/interval/branch/master)\n[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/gpslab/interval.svg?maxAge=3600)](https://scrutinizer-ci.com/g/gpslab/interval/?branch=master)\n[![StyleCI](https://styleci.io/repos/75078831/shield?branch=master)](https://styleci.io/repos/75078831)\n[![License](https://img.shields.io/packagist/l/gpslab/interval.svg?maxAge=3600)](https://github.com/gpslab/interval)\n\nInterval Value Objects\n======================\n\nThis is a library with a set of classes intended to describe intervals as\n[Value Objects](https://en.wikipedia.org/wiki/Value_object) and perform operations on them.\n\n## Installation\n\nPretty simple with [Composer](http://packagist.org), run:\n\n```sh\ncomposer require gpslab/interval\n```\n\n## Interval type\n\nThis library is supports [interval types](https://en.wikipedia.org/wiki/Interval_(mathematics)).\n\n* `[a, b] = [a, b] = {x ∈ ℝ | a ≤ x ≤ b}` - Closed\n* `[a, b) = [a, b[ = {x ∈ ℝ | a ≤ x \u003c b}` - Half-closed\n* `(a, b] = ]a, b] = {x ∈ ℝ | a \u003c x ≤ b}` - Half-open\n* `(a, b) = ]a, b[ = {x ∈ ℝ | a \u003c x \u003c b}` - Open\n\n## Intervals\n\n* Number\n* Date\n* Time\n* DateTime\n* Week\n* Month\n* Year\n* IPv4\n* IPv6\n* IPv4Network\n* IPv6Network\n\n\n## Usage intervals\n\nCreate interval `[1, 5)`\n\n```php\n$interval = NumberInterval::halfClosed(1, 5);\necho $interval-\u003estart(); // 1\necho $interval-\u003eend(); // 5\n\n// convert to string\n$string = (string)$interval;\necho $string; // [1, 5)\n\n// restore from string\n$new_interval = NumberInterval::fromString($string);\n$interval == $new_interval; // true\n$interval-\u003eequal($new_interval); // true\n```\n\nChange intervals\n\n```php\n$interval = NumberInterval::halfClosed(1, 5);\n// created a new interval instance\n$new_interval = $interval-\u003ewithStart(new NumberIntervalPoint(2));\n$interval-\u003estart() != $new_interval-\u003estart(); // true\n```\n\nIPv4 network\n\n```php\n// from CIDR\n$network = IPv4Network::fromCIDR('192.168.0.0', 16);\necho $network-\u003estart(); // 192.168.0.0\necho $network-\u003eend(); // 192.168.255.255\n\n$network-\u003econtains('192.168.13.74'); // true\n\n// from ip mask\n$new_network = IPv4Network::fromMask('192.168.0.0', '255.255.0.0');\n$network-\u003eequal($new_network); // true\n```\n\nLocal network\n\n```php\nfunction isLocalNetworkHost($host)\n{\n    // is IPv6\n    if (strpos($host, ':') !== false) {\n        // RFC 4193\n        return IPv6Network::fromString('fc00::/7')-\u003econtains($host);\n    }\n\n    // RFC 1918\n    return\n        IPv4Network::fromString('10/8')-\u003econtains($host) ||\n        IPv4Network::fromString('172.16/12')-\u003econtains($host) ||\n        IPv4Network::fromString('192.168/16')-\u003econtains($host)\n    ;\n}\n```\n\n## Interval operations\n\n* `equal` - Checks if this Interval is equal to the specified interval;\n* `contains` - Does this interval contain the specified point;\n* `intersects` - Does this interval intersect the specified interval;\n* `intersection` - Gets the intersection between this interval and another interval;\n* `cover` - Gets the covered interval between this Interval and another interval;\n* `gap` - Gets the gap between this interval and another interval;\n* `abuts` - Does this interval abut with the interval specified;\n* `join` - Joins the interval between the adjacent;\n* `union` - Gets the union between this interval and another interval;\n* `before` - The point is before the interval;\n* `after` - The point is after the interval.\n\n## Iterate intervals\n\nThe following intervals support iteration:\n\n* Number\n* Date\n* Time\n* DateTime\n* Week\n* Month\n* Year\n* IPv4\n* IPv4Network\n\n### Example usage\n\nUse step `1` and closed interval type `[1, 5]`\n\n```php\n$interval = NumberInterval::closed(1, 5);\n\n$points_in_interval = [];\nforeach ($interval-\u003eiterate() as $point) {\n    $points_in_interval[] = $point;\n}\n\n$points_in_interval == [1, 2, 3, 4, 5]; // true\n```\n\nUse step `2` and open interval type `(0, 10)`\n\n```php\n$step = 2;\n$interval = NumberInterval::open(0, 10);\n\n$points_in_interval = [];\nforeach ($interval-\u003eiterate($step) as $point) {\n    $points_in_interval[] = $point;\n}\n\n$points_in_interval == [2, 4, 6, 8]; // true\n```\n\nIterate IPv4 interval\n\n```php\n$expected = [\n    '10.0.1.2',\n    '10.0.1.4',\n    '10.0.1.6',\n    '10.0.1.8'\n];\n$step = 2;\n$interval = IPv4Interval::open('10.0.1.0', '10.0.1.10');\n\n$points_in_interval = [];\nforeach ($interval-\u003eiterate($step) as $point) {\n    $points_in_interval[] = $point;\n}\n$points_in_interval == $expected; // true\n```\n\nIterate date interval\n\n```php\n$expected = [\n    '2017-03-03',\n    '2017-03-05',\n    '2017-03-07',\n    '2017-03-09',\n];\n$step = new \\DateInterval('P2D');\n$interval = DateInterval::open(new \\DateTime('2017-03-01'), new \\DateTime('2017-03-11'));\n\n$points_in_interval = [];\nforeach ($interval-\u003eiterate($step) as $point) {\n    $points_in_interval[] = $point-\u003eformat('Y-m-d');\n}\n\n$points_in_interval == $expected; // true\n```\n\n## Persistence in Doctrine\n\nYou cat use intervals as\n[Custom Mapping Types](http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html)\nfor Doctrine.\n\n```php\nType::addType('NumberInterval', 'GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\NumberIntervalType');\n$em-\u003egetConnection()-\u003egetDatabasePlatform()-\u003eregisterDoctrineTypeMapping('NumberInterval', 'NumberInterval');\n```\n\nYou cat [registration](http://symfony.com/doc/current/doctrine/dbal.html#registering-custom-mapping-types) custom\nDoctrine mapping types in Symfony\n\n```yml\n# config/packages/doctrine.yml\ndoctrine:\n    dbal:\n        types:\n            NumberInterval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\NumberIntervalType\n            DateInterval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\DateIntervalType\n            TimeInterval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\TimeIntervalType\n            DateTimeInterval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\DateTimeIntervalType\n            WeekInterval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\WeekIntervalType\n            MonthInterval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\MonthIntervalType\n            YearInterval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\YearIntervalType\n            IPv4Interval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\IPv4IntervalType\n            IPv6Interval: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\IPv6IntervalType\n            IPv4Network: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\IPv4NetworkType\n            IPv6Network: GpsLab\\Component\\Interval\\Persistence\\Doctrine\\DBAL\\Types\\IPv6NetworkType\n```\n\n## License\n\nThis bundle is under the [MIT license](http://opensource.org/licenses/MIT). See the complete license in the file: LICENSE\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgpslab%2Finterval","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgpslab%2Finterval","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgpslab%2Finterval/lists"}