Create a gist now

Instantly share code, notes, and snippets.

@Kcko /DateTime.php forked from 66Ton99/DateTime.php
Last active May 25, 2018

Embed
DateTime
<?php
namespace MyNamespace;
$date = new ADateTime('2018-03-28');
$date->sub(new \DateInterval('P1M'));
echo $date->format('Y-m-d') . "\n";
/**
* @author Ton Sharp <66Ton99@gmail.com>
*/
class ADateTime extends \DateTime
{
/**
* @param int|null $year
* @param int|null $month
* @param int|null $day
*
* @return $this
*/
public function setDate($year, $month, $day)
{
if (null == $year) {
$year = $this->format('Y');
}
if (null == $month) {
$month = $this->format('n');
}
if (null == $day) {
$day = $this->format('j');
}
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$day = $day > $daysInMonth ? $daysInMonth : $day;
$return = parent::setDate($year, $month, $day);
return $return;
}
/**
* @inheritdoc
*/
public function modify($modify)
{
$pattern = '/( ?[-+]?\d?\w* months?)?( ?[-+]?\d?\w* years?)?/i';
$modify = preg_replace_callback(
$pattern,
function($matches) use ($pattern) {
if (empty($matches[0])) {
return;
}
$orDay = $this->format('j');
$this->setDate(null, null, 1);
if (!parent::modify($matches[0])) {
return;
}
$this->setDate(null, null, $orDay);
return;
},
$modify
);
if ($modify = trim($modify)) {
return parent::modify($modify);
}
return $this;
}
/** {@inheritdoc} */
public function add(\DateInterval $interval)
{
$format = $this->intervalToString($interval, $interval->invert ? '-' : '+');
return $this->modify($format);
}
/** {@inheritdoc} */
public function sub(\DateInterval $interval)
{
$format = $this->intervalToString($interval, $interval->invert ? '+' : '-');
return $this->modify($format);
}
/**
* @param DateInterval $interval
* @param string $sign
*
* @return string
*/
protected function intervalToString(\DateInterval $interval, $sign)
{
$format = vsprintf('%1$s%2$d years %1$s%3$d months %1$s%4$d days %1$s%5$d hours %1$s%6$d minutes %1$s%7$d seconds', [
$sign,
$interval->y,
$interval->m,
$interval->d,
$interval->h,
$interval->i,
$interval->s,
]);
return $format;
}
}
<?php
require_once __DIR__ . '/DateTime.php';
class DateTimeTest extends \PHPUnit_Framework_TestCase
{
public function providerSetDate()
{
$now = new \MyNamespace\DateTime();
return array(
array('2014-02-28', 31, 2),
array('2014-02-01', 1, 2),
array('2014-06-30', 31, 6),
array($now->format('Y-m-d'), null, null, null),
);
}
/**
* @test
* @dataProvider providerSetDate
*/
public function setDate($result, $day, $month, $year = '2014')
{
$dateTime = new \MyNamespace\DateTime();
$dateTime->setDate($year, $month, $day);
$this->assertEquals($result, $dateTime->format('Y-m-d'));
}
public function providerModify()
{
return array(
array('2014-02-28', '0 day 0 month 0 year'),
array('2014-01-28', 'next month'),
array('2014-01-28', 'next months'),
array('2014-01-02', '+1 month', '2014-02-02'),
array('2014-01-31', '1 months'),
array('2014-03-31', '-1 month'),
array('2012-02-29', '24 month'),
array('2016-02-29', '-24 months'),
array('2014-02-27', 'next day'),
array('2014-02-27', '1 day'),
array('2014-02-27', '+1 day'),
array('2013-02-01', '-1 day next month next year'),
array('2013-01-27', '1 day 1 month 1 year'),
array('2015-04-01', '-1 day -1 month -1 year'),
array('2011-12-26', '2 day 2 month 2 year'),
array('2011-12-31', '2 month 2 year'),
);
}
/**
* @test
* @dataProvider providerModify
*/
public function modify($date, $shift, $result = '2014-02-28')
{
$dateTime = new \MyNamespace\DateTime($date);
$dateTime->modify($shift);
$this->assertEquals($result, $dateTime->format('Y-m-d'));
}
/**
* @test
* @expectedException PHPUnit_Framework_Error_Warning
*/
public function modifyError()
{
$dateTime = new \MyNamespace\DateTime();
$dateTime->modify('2 month sdfg year');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment