gpslab/interval

DDD 时间区间结构

v0.2.4 2021-09-30 09:23 UTC

This package is auto-updated.

Last update: 2024-09-16 19:05:38 UTC


README

GitHub Actions Latest Stable Version Code Coverage Scrutinizer Code Quality StyleCI License

时间区间值对象

这是一个库,包含一系列类,旨在将区间描述为值对象,并在其上执行操作。

安装

使用Composer非常简单,运行

composer require gpslab/interval

时间区间类型

此库支持时间区间类型

  • [a, b] = [a, b] = {x ∈ ℝ | a ≤ x ≤ b} - 闭区间
  • [a, b) = [a, b[ = {x ∈ ℝ | a ≤ x < b} - 半开区间
  • (a, b] = ]a, b] = {x ∈ ℝ | a < x ≤ b} - 半闭区间
  • (a, b) = ]a, b[ = {x ∈ ℝ | a < x < b} - 开区间

时间区间

  • 数字
  • 日期
  • 时间
  • 日期时间
  • IPv4
  • IPv6
  • IPv4网络
  • IPv6网络

使用时间区间

创建时间区间 [1, 5)

$interval = NumberInterval::halfClosed(1, 5);
echo $interval->start(); // 1
echo $interval->end(); // 5

// convert to string
$string = (string)$interval;
echo $string; // [1, 5)

// restore from string
$new_interval = NumberInterval::fromString($string);
$interval == $new_interval; // true
$interval->equal($new_interval); // true

更改时间区间

$interval = NumberInterval::halfClosed(1, 5);
// created a new interval instance
$new_interval = $interval->withStart(new NumberIntervalPoint(2));
$interval->start() != $new_interval->start(); // true

IPv4网络

// from CIDR
$network = IPv4Network::fromCIDR('192.168.0.0', 16);
echo $network->start(); // 192.168.0.0
echo $network->end(); // 192.168.255.255

$network->contains('192.168.13.74'); // true

// from ip mask
$new_network = IPv4Network::fromMask('192.168.0.0', '255.255.0.0');
$network->equal($new_network); // true

本地网络

function isLocalNetworkHost($host)
{
    // is IPv6
    if (strpos($host, ':') !== false) {
        // RFC 4193
        return IPv6Network::fromString('fc00::/7')->contains($host);
    }

    // RFC 1918
    return
        IPv4Network::fromString('10/8')->contains($host) ||
        IPv4Network::fromString('172.16/12')->contains($host) ||
        IPv4Network::fromString('192.168/16')->contains($host)
    ;
}

时间区间操作

  • equal - 检查此时间区间是否与指定的区间相等;
  • contains - 此区间是否包含指定的点;
  • intersects - 此区间是否与指定的区间相交;
  • intersection - 获取此区间与另一个区间的交集;
  • cover - 获取此时间区间与另一个区间之间的覆盖区间;
  • gap - 获取此区间与另一个区间之间的间隙;
  • abuts - 此区间是否与指定的区间相邻;
  • join - 将相邻的区间连接起来;
  • union - 获取此区间与另一个区间的并集;
  • before - 点在区间之前;
  • after - 点在区间之后。

迭代时间区间

以下时间区间支持迭代

  • 数字
  • 日期
  • 时间
  • 日期时间
  • IPv4
  • IPv4网络

示例用法

使用步长 1 和闭区间类型 [1, 5]

$interval = NumberInterval::closed(1, 5);

$points_in_interval = [];
foreach ($interval->iterate() as $point) {
    $points_in_interval[] = $point;
}

$points_in_interval == [1, 2, 3, 4, 5]; // true

使用步长 2 和开区间类型 (0, 10)

$step = 2;
$interval = NumberInterval::open(0, 10);

$points_in_interval = [];
foreach ($interval->iterate($step) as $point) {
    $points_in_interval[] = $point;
}

$points_in_interval == [2, 4, 6, 8]; // true

迭代IPv4区间

$expected = [
    '10.0.1.2',
    '10.0.1.4',
    '10.0.1.6',
    '10.0.1.8'
];
$step = 2;
$interval = IPv4Interval::open('10.0.1.0', '10.0.1.10');

$points_in_interval = [];
foreach ($interval->iterate($step) as $point) {
    $points_in_interval[] = $point;
}
$points_in_interval == $expected; // true

迭代日期区间

$expected = [
    '2017-03-03',
    '2017-03-05',
    '2017-03-07',
    '2017-03-09',
];
$step = new \DateInterval('P2D');
$interval = DateInterval::open(new \DateTime('2017-03-01'), new \DateTime('2017-03-11'));

$points_in_interval = [];
foreach ($interval->iterate($step) as $point) {
    $points_in_interval[] = $point->format('Y-m-d');
}

$points_in_interval == $expected; // true

Doctrine中的持久性

您可以将区间用作自定义映射类型,用于Doctrine。

Type::addType('NumberInterval', 'GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\NumberIntervalType');
$em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('NumberInterval', 'NumberInterval');

您可以在Symfony中注册自定义Doctrine映射类型

# config/packages/doctrine.yml
doctrine:
    dbal:
        types:
            NumberInterval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\NumberIntervalType
            DateInterval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\DateIntervalType
            TimeInterval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\TimeIntervalType
            DateTimeInterval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\DateTimeIntervalType
            WeekInterval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\WeekIntervalType
            MonthInterval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\MonthIntervalType
            YearInterval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\YearIntervalType
            IPv4Interval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\IPv4IntervalType
            IPv6Interval: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\IPv6IntervalType
            IPv4Network: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\IPv4NetworkType
            IPv6Network: GpsLab\Component\Interval\Persistence\Doctrine\DBAL\Types\IPv6NetworkType

许可证

此包采用MIT许可证。请参阅文件中的完整许可证:LICENSE