此包已被弃用,不再维护。作者建议使用 nesbot/carbon 包。

处理时间单位(小时、分钟、秒等)的简单方法。

1.0.2 2015-11-28 19:41 UTC

This package is auto-updated.

Last update: 2022-03-29 09:36:57 UTC


README

Build Status Stable Latest Unstable Version Scrutinizer Code Quality License

SensioLabsInsight

Loom 是处理时间单位(小时、分钟、秒等)的一种非常简单的方法。

为什么?

因为谁知道这意味着什么?

$something = someFunctionWithTime(7200);

7200没有意义。秒?小时?年?所以我开始编写 Loom,以使处理时间常量时更易于阅读

$loom = Loom::make()->fromHours(2);
$something = someFunctionWithTime($loom->getSeconds());

当然,它更长,但更容易阅读。此外,你还可以获得一些功能,将一个时间单位转换为另一个时间单位。

Loom 在 PHP 5.4、5.5、5.6、7.0 和 HHVM 上进行了测试。除了测试时需要 PHPUnit 以外,它没有其他依赖项。它是框架无关的,但我将它用于许多项目,这些项目主要使用 Laravel 框架,因此它在那里经过了良好的测试。

请告诉我你如何以及何时使用它。

安装

通过 Composer 安装 Loom,将以下内容添加到你的 composer.json 文件的 requires 部分。

{
	"require": {
		"warrickbayman/loom": "~1.0"
	}
}

在你的项目根目录中运行 composer update 以安装 Loom。

使用

创建新的 Loom 对象

在实例化 Loom 时,有三种方法可供选择。

创建一个新的 Loom 对象实例

$loom = new Loom\Loom(new Loom\Seconds(100));

为了避免每次都使用 Loom 命名空间,你可以将其添加到你的 use 子句

use Loom\Loom;
use Loom\Seconds;

class MyLoomClass
{
	public function translate()
	{
		$loom = new Loom(new Seconds(100));
	}
}

建议的方法是将 LoomFactory 类注入到你的构造函数中,并从那里调用可用的创建方法

class MyLoomClass
{
	private $loom;
	
	public function __construct(Loom\LoomFactory $loom)
	{
		$this->loom = $loom->fromSeconds(240);
	}
	
	public function translate()
	{
		return $this->loom->getMinutes();        // 4
	}
}

最后,最简单的方法是调用 Loom 对象上的静态 make() 方法,该方法返回一个新的 LoomFactory 实例。由于 LoomFactory 上的创建方法返回一个新的 Loom 对象,你可以将转换方法链接到工厂创建中,并使用单行代码使用 Loom

$minutes = Loom::make()->fromHours(2)->getMinutes();    // 120

LoomFactory 上的创建方法

$loomFactory->fromMicroseconds($microseconds);
$loomFactory->fromMilliseconds($milliseconds);
$loomFactory->fromSeconds($seconds);
$loomFactory->fromMinutes($minutes);
$loomFactory->fromHours($hours);
$loomFactory->fromDays($days);
$loomFactory->fromWeeks($weeks);
$loomFactory->fromMonths($months);
$loomFactory->fromYears($years);

还有一个 fromLoom() 方法,该方法通过传入参数创建一个新的 Loom 对象实例。

注意:曾经将 fromLoom() 命名为 copy(),但从未进行过文档说明。以防万一,我已经弃用了 copy() 方法,直到下一个主要版本。

使用 DateTime

LoomFactory 对象还提供了一个 fromDateTime 方法,允许您从一个 DateTime 对象创建一个 Loom 对象。

$loom = $loomFactory->fromDateTime(new \DateTime('2015-01-21');

新的 Loom 对象将表示自 Epoc(1970-01-01 00:00:00)以来经过的时间量。换句话说,这样做...

var_dump($loom->getHours());

... 将获得自 1970 年 1 月 1 日以来经过的小时数。当你需要获取两个特定日期之间的差异时,这会变得更有用。

$loom = Loom::make()->fromDateTime(new \DateTime('2015-01-21'));
$result = $loom->diff(Loom::make()->fromDateTime(new \DateTime('2015-01-27'));

var_dump($result->getDays());     // 6
var_dump($result->getHours());    // 144
var_dump($result->getMinutes());  // 8640

由于像nesbot\carbon这样的库只是扩展了DateTime对象,您也可以这样做...

$loom = Loom::make()->fromTime(\Carbon\Carbon::now());

获取器

Loom提供了一些简单的方法来实现不同单位之间的转换。

$microseconds = $loom->getMicroseconds();
$milliseconds = $loom->getMilliseconds();
$seconds = $loom->getSeconds();
$minutes = $loom->getMinutes();
$hours = $loom->getHours();
$days = $loom->getDays();
$weeks = $loom->getWeeks();
$months = $loom->getMonths();
$years = $loom->getYears();

每个获取器都返回一个浮点数。

每月天数取平均值!

默认情况下,Loom会平均每月的天数。这意味着在处理月份时结果可能会有意外。

$loom = Loom::make()->fromDays(30);
var_dump($loom->getMonths());		// Returns 0.98630136986301


$loom = Loom::make()->fromMonths(1);
var_dump($loom->getDays());			// Returns 30.416666666667

为了避免这种情况,getMonths()方法将接受一个整数作为一个月的天数,因此您可以这样做:

$loom = Loom::make()->fromDays(60);
var_dump($loom->getMonths(30));     // 2

在从月份创建新的Loom对象时,也可以这样做。

$loom = Loom::make()->fromMonths(12, 31);
var_dump($loom->getDays());		// 372

太阳年

一年不是正好365天长。相反,它比这略微长一些。当前的平均太阳年是365天,5小时,48分钟和45.19秒。Loom可以通过将布尔值true作为第二个参数传递给使用年方法时,使用365.2421897天的太阳年长度来代替简单的365天。默认情况下,Loom使用平坦的365天来表示一年。

$loom = Loom::make()->fromYears(1, true);
var_dump($loom->getDays());		// 365.2421897


$loom = Loom:make()->fromMonths(12);
var_dump($loom->getYears(true));	// 0.99933690656

差异

您可以使用diff()方法获取两个Loom对象之间的差异。该方法返回一个新的Loom对象。

$loom1 = Loom::make()->fromDays(1);
$loom2 = Loom::make()->fromHours(48);

$diff = $loom1->diff($loom2);

var_dump($diff->getHours());		// Returns 24.

调用哪个对象执行diff()方法无关紧要。无论哪种方式,结果都将相同。

还有两个节省时间的方法,它们返回到特定时间或从特定时间以来的差异。名为until()since()的方法仅在首先从PHP的DateTime对象创建Loom对象时才真正有用。两种方法都返回一个新的Loom对象。

$loomPast = Loom::make()->fromDateTime(new \DateTime('now - 5 days'));
$loomFuture = Loom::make()->fromDateTime(new \DateTime('now + 10 days'));

var_dump($loomPast->since()->getHours());       // Returns 120.
var_dump($loomFuture->until()->getHours());     // Returns 240.

since()until()方法只是对两个Loom对象执行diff(),由于diff()方法总是会返回一个正数,因此since()until()方法实际上是相同的。它们的存在只是为了帮助使您的代码更加易于阅读。

比较

也存在许多比较方法。

$loom1 = Loom::make()->fromDays(1);
$loom2 = Loom::make()->fromHours(48);

// Equal to
$loom1->eq($loom2);			// false

// Not equal to
$loom1->neq($loom2);		// true

// Greater than
$loom1->gt($loom2);			// false

// Greater than or equal to
$loom1->gte($loom2);		// false

// Less than
$loom1->lt($loom2);			// true

// Less than or equal to
$loom1->lte($loom2);		// true

这里重要的是比较方法调用的对象。您调用的对象总是在等式的左边。

之间

Loom提供了一种检查一个单位是否介于两个其他单位之间的方法。该方法接受两个Loom对象,这意味着您可以使用任何创建方法。

$loom = Loom::make()->fromSeconds(100);
if ($loom->isBetween(
	Loom::make()->fromMinutes(1),
	Loom::make()->fromMinutes(2)
)) {
	echo 'Hooray!';
}

isBetween方法还接受第二个布尔参数,用于指定限制是包含还是排除。默认情况下,isBetween不包含限制。换句话说,如果您正在检查的值等于上限,则结果将是false

您可以通过传递布尔值true作为第三个参数,让isBetween包含限制进行比较。

$loom = Loom::make()->fromSeconds(120);

// Default is exclusive. Returns false.
var_dump($loom->isBetween(
	Loom::make()->fromMinutes(1),
	Loom::make()->fromMinutes(2)
));	

// Inclusive. Returns true.
var_dump($loom->isBetween(
	Loom::make()->fromMinutes(1),
	Loom::make()->fromMinutes(2),
	true
));

简单算术

您可以通过add()sub()方法执行一些简单的算术。

	$loom = Loom::make()->fromMinutes(2);
	$loom->add(Loom::make()->fromSeconds(30));
	var_dump($loom->getSeconds())			// 150
	
	$loom->sub(Loom::make()->fromHours(1));
	var_dump($loom->getMilliseconds);		// 0

Loom对象永远不会有一个负值。从较小的Loom减去较大的Loom将始终得到0。

算术方法将接受AbstractUnit的实例,因此您不需要创建另一个Loom对象。您只需将单元传递给方法即可。

	$loom = Loom::make()->fromMinutes(2);
	$loom->add(new Loom\Seconds(60));
	var_dump($loom->getSeconds());		// 180
	
	$loom->sub(new Loom\Minutes(2));
	var_dump($loom->getSeconds());		// 60

Loom 集合

目前,正在开发一个新的 LoomCollection 类,并且可在 develop 分支上使用。Loom 集合基于 Laravel 的 Collection 类,但内置了一些 Loomness 特性。

新的 LoomCollection 类的构造函数接受一个 Loom 对象数组,但您也可以创建一个空的集合。

$collection = new Loom\LoomCollection();

Loom 集合只能包含 Loom 对象。如果您尝试添加其他任何内容,将会抛出异常。

推入、弹出、前置、移除

操作 LoomCollection 的内容非常简单。使用 push 方法将新的 Loom 对象推入集合的末尾,使用 pop 方法移除最后一个 Loom 对象,使用 prepend 方法将 Loom 对象插入到集合的开头,使用 shift 方法移除第一个对象。

// Add to the end of the collection
$collection->push(new Loom::make()->fromMinutes(4));
// Add to the beginning of the collection
$collection->prepend(new Loom::make()->fromMinutes(10));

// Pull the last object from the collection
$loom = $collection->pop();
// Pull the first object from the collection
$loom = $collection->shift();

查找

Loom 提供了一种简单的方法从集合中检索单个 Loom 对象。您可以使用 first() 方法始终获取第一个 Loom 对象。同样,last() 方法将始终返回集合中的最后一个对象。

$first = $collection->first();
$last = $collection->last();

pop()shift() 不同,这些方法不会更改集合,只会返回 Loom 对象。

有时,您可能需要获取最短或最长的 Loom 对象。您可以使用 shortest()longest() 方法做到这一点。还有一个 earliest() 方法,它是 shortest 的别名,以及一个 latest(),它是 longest 的别名。

$shortest = $collection->shortest();
$longest = $collection->longest();

过滤

没有集合类会没有过滤集合内容的能力。最好的起点是 filter 方法,它接受一个闭包。将 Loom 对象作为参数传递给闭包。如果闭包返回布尔值 true,则该对象将被包括在过滤结果中。

$filtered = $collection->filter(function(Loom $loom)
{
    return $loom->gt(Loom::make()->fromMinutes(6);
});

然而,Loom 还包括一些额外的过滤方法,使此过程更加简单。after() 方法将返回所有在指定 Loom 之后出现的 Loom 对象,而 before() 方法将返回所有在指定 Loom 之前出现的对象。

// After
$newCollection = $collection->after(Loom::make()->fromMinutes(8));

// Before
$newCollection = $collection->before(Loom::make()->fromMinutes(6));

还有一个 between() 方法,它将返回在指定开始和结束 Loom 之间的对象。

$newCollection = $collection->between(
    Loom::make()->fromMinutes(5),
    Loom::make()->fromHours(1)
);    

迭代

LoomCollection 类还包括一个 each() 方法,它接受一个闭包,该闭包将遍历集合中的每个 Loom。

$newCollection = $collection->each(function(Loom $loom)
{
    echo $loom->getMinutes();
});

排序

可以使用名为 sort() 的方法对集合进行排序。默认情况下,sort() 将按升序(最小的 Loom 首先出现)排序,但您可以通过传递布尔值 true 作为参数来反转排序。

// Ascending
$sorted = $collection->sort();

// Descending
$sorted = $collection->sort(true);

范围

Loom 提供了一个有趣的功能,允许您创建一系列的 Loom 对象。范围始终作为 Loom 集合返回。创建范围相对简单。现在,在 Loom 类上不再调用 make() 静态方法,而是在 Loom 类上有一个新的 makeRange() 静态方法。您可以将单个 Loom 对象传递给 from() 方法,并将一个传递给 to() 方法。 steps() 方法接受一个整数参数,并返回一个新的 LoomCollection 实例。

$range = Loom::makeRange()
    ->from(Loom::make()->fromSeconds(1))
    ->to(Loom::make()->fromSeconds(10))
    ->steps(10);

这将返回一个新的包含 10 个 Loom 对象的 LoomCollection,第一个对象为 1 秒,最后一个对象为 10 秒。