/ Gists / DateTime
On gists

DateTime

PHP
DateTime

DateTimeTest.php Raw #

<?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');
    }
}

DateTime.php Raw #

<?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;
    }







}