choval/datetime

PHP的DateTime的灵活替代品

v0.3.0 2023-11-12 13:05 UTC

This package is auto-updated.

Last update: 2024-09-12 14:46:49 UTC


README

这是PHP的DateTime的替代品。
添加了一些解析器,以简化使用,请参阅使用方法和差异。

安装

composer require choval/datetime

简单替换

之前

$a = new DateTime;

替换后

use Choval\DateTime;
$a = new DateTime;

以下示例将使用完整的类名,以避免混淆。

用法

// Working with timestamps
$t = 946684800;     // 2000-01-01 00:00:00+00:00

// An int is interpretated as a timestamp
$a = new Choval\DateTime( $t );
echo $a->format('c');       // 2000-01-01T00:00:00+00:00
echo $a->getTimestamp();    // 946684800

// Using PHP's DateTime for the same task
$b = \DateTime::createFromFormat( 'U', $t );
echo $b->format('c');       // 2000-01-01T00:00:00+00:00
echo $b->getTimestamp();    // 946684800

// Still a drop-in ;-)
$c = Choval\DateTime::createFromFormat( 'U', $t );
echo $c->format('c');       // 2000-01-01T00:00:00+00:00
echo $c->getTimestamp();    // 946684800

差异

如果替换PHP的DateTime,此类几乎完全相同。除了构造函数处理低数值时的整数作为时间戳。

// Flexible timezone parameter
// -3, '-03' , '-0300', '-03:00', 'America/Argentina/Buenos_Aires'
// or (new DateTimeZone('America/Argentina/Buenos_Aires'))
$d = new Choval\DateTime( '2000-01-01', '-0300');
echo $d->format('c');       // 2000-01-01T00:00:00-03:00
echo $d->getTimestamp();    // 946674000

// The constructor accepts a format as the third parameter
$e = new Choval\DateTime( '31/01/2000', '-3', 'd/m/Y' );
echo $e->format('c');       // 2000-01-31T00:00:00-03:00

// Similarly in PHP's DateTime
$f = \DateTime::createFromFormat( 'd/m/Y', '31/01/2000', (new DateTimeZone('America/Argentina/Buenos_Aires')) );

// Yet again, still a drop-in ;-)
$g = Choval\DateTime::createFromFormat( 'd/m/Y', '31/01/2000', (new DateTimeZone('America/Argentina/Buenos_Aires')) );

// Or ease it
$h = Choval\DateTime::createFromFormat( 'd/m/Y', '31/01/2000', '-03:00' );

// `add` and `sub` accept DateTime modifier formats, DateInterval objects or interval_spec (ie: P1Y for 1 year)
$e->add('+3 hours');
$e->add('PT3H');
$e->add(new DateInterval('PT3H'));
$e->modify('+3 hours');
echo $e->format('c');       // 2000-01-31T12:00:00-03:00

构造函数

__constructor方法允许第三个参数来传递第一个参数的格式。

__construct(
	string $time='now',
	$timezone=NULL,
	string $format=NULL
	)

这允许传递自定义格式的日期时间字符串。

$a = new Choval\DateTime( '31/12/2019', '-3', 'd/m/Y' );
echo $a->format('c');	// 2019-12-31T00:00:00-03:00

格式

format方法允许第二个参数来传递输出的时间区域,否则使用对象的时间区域。

传入的时间区域不会改变对象本身的时间区域。请参阅以下示例

$a = new Choval\DateTime('2019-01-01 00:00:00', '-03:00');

echo $a->format('c');
// 2019-01-01T00:00:00-03:00

echo $a->format('c', '+08:00');
// 2019-01-01T11:00:00+08:00

echo $a->format('c', 'UTC');
// 2019-01-01T03:00:00+00:00

echo $a->format('c');
// 2019-01-01T00:00:00-03:00
// Notice how the original timezone is kept

附加功能

以下方法被添加以移动日期并在字符串形式打印/返回它们。

时间修改器

  • startOfDay(void) : self
  • midDay(void) : self
  • endOfDay(void) : self
$a = new Choval\DateTime('2000-01-01 12:34:56', 'UTC');
echo $a->startOfDay()->format('H:i:s');	// 00:00:00
echo $a->midDay()->format('H:i:s');		// 12:00:00
echo $a->endOfDay()->format('H:i:s');	// 23:59:59

echo $a->format('c');			// 2000-01-01T23:59:59+00:00

$a->setTimezone('+01:00');
echo $a->format('H:i:s');					// 00:59:59
echo $a->format('c');			// 2000-01-02T00:59:59+01:00
echo $a->format('c', 'UTC');	// 2000-01-01T23:59:59+00:00

echo $a->endOfDay()->format('H:i:s');	// 23:59:59
echo $a->format('c');			// 2000-01-02T23:59:59+01:00

年份日期修改器

  • firstDayOfYear([int $year]) : self
  • lastDayOfYear([int $year]) : self
$year = new Choval\DateTime;
$since = $year->firstDayOfYear()->startOfDay();
$till = $year->lastDayOfYear()->endOfDay();

// Useful for SQL
$sql = "SELECT * FROM users WHERE created >= ? AND created <= ?";
$q = $db->query($sql, [ $since,$till ]);
$rows = yield $q->fetchAll();

月份日期修改器

  • firstDayOfMonth([int $month]) : self
  • lastDayOfMonth([int $month]) : self
  • firstSundayOfMonth([int $month]) : self
  • lastSundayOfMonth([int $month]) : self
  • firstMondayOfMonth([int $month]) : self
  • lastMondayOfMonth([int $month]) : self
  • firstFridayOfMonth([int $month]) : self
  • lastFridayOfMonth([int $month]) : self
  • nextMonth([int $day]) : self
  • prevMonth([int $day]) : self
$d = new Choval\DateTime('2019-10-31');
$d->add('1 month');
echo $d->format('Y-m-d');
// Returns 2019-12-01, just like PHP's DateTime modifiers

$d = new Choval\DateTime('2019-10-31');
$d->nextMonth();
echo $d->format('Y-m-d');
// Returns 2019-11-30, last day of next month

// Using nextMonth/prevMonth, the target day can be passed
// This is useful for billing dates
$d->nextMonth(31);
echo $d->format('Y-m-d');
// Returns 2019-12-31, last day of next month, but
// original day was 31, so it gets pushed to 31.

工作日

非周末和非假日(见假日)的日子。

  • isWorkDay(void) : bool
  • firstWorkDayOfMonth([int $month]) : self
  • lastWorkDayOfMonth([int $month]) : self
  • firstWorkDayOfYear([int $year]) : self
  • lastWorkDayOfYear([int $year]) : self

假日

  • setHolidays(array $holidays) : DateTime
  • getHolidays(void) : array
  • addHoliday(string $date)
  • isHoliday(void) : bool
$a = new Choval\DateTime('2019-06-30');
// Holidays need to be in YYYY-MM-DD or MM-DD format
// Set Holidays, overwrites current list.
$a->setHolidays([
	'01-01',	// New year
	'12-25',	// Christmas
]);

// A holiday that is in one specific year
$a->addHoliday('2019-01-02');

// Gets the holidays
$holidays = $a->getHolidays();

// First workday of the year
// Notice how its not new year,
// not 2019-01-02 and not on a weekend.
$b = clone $a;
$b->firstWorkDayOfYear();
echo $b->format('Y-m-d');		// Returns 2019-01-03 
// since the 2nd of january was added as aholiday for 2019.

$b->sub('1 year')->firstWorkDayOfYear();
echo $b->format('Y-m-d');		// Returns 2018-01-02
// 2019-01-02 was added as a holiday with a year,
// meaning that only on that year its a holiday.
// New year was added without a year, meaning every year.

格式

  • atom(void) : string
  • iso(void) : string
  • cookie(void) : string
  • iso8601(void) : string
  • rfc822(void) : string
  • rfc850(void) : string
  • rfc1036(void) : string
  • rfc1123(void) : string
  • rfc2822(void) : string
  • rfc3339(void) : string
  • rfc3339Extended(void) : string
  • rss(void) : string
  • w3c(void) : string

请注意,ISO8601常量返回没有冒号格式的时间区域。如果需要,请使用atom格式或iso方法,它们都返回Y-m-d\TH:i:sP