PHP的成熟日期

时间:2015-10-29 14:39:01

标签: php date

修改:

成熟日期,它是什么?

我不是母语为英语的人。对于那个很抱歉。我认为我们能做的最好的事情就是定义到期日。

  

到期日是指示付款截止日期的日期   发票在BtoB中,到期日表示客户何时   我想支付给我们,在合同期间定义的通常是1到3个月之后的日期   该法案出版后。这是一个计算数据,和   在我的应用程序中使用以下代码实现。

我在我的发票模块中有这个代码,我把它解压缩,你可以测试:

<?php
class Config
{
    protected $amountDelayedDays;
    protected $paymentDay;
    protected $paymentCondition;

    public function getAmountDelayedDays()
    {
        return $this->amountDelayedDays;
    }

    public function getPaymentCondition()
    {
        return $this->paymentCondition;
    }

    public function getPaymentDay()
    {
        return $this->paymentDay;
    }


    public function setAmountDelayedDays($days)
    {
        $this->amountDelayedDays = $days;
        return $this;
    }

    public function setPaymentDay($days)
    {
        $this->paymentDay = $days;
        return $this;
    }

    public function setPaymentCondition($condition)
    {
        $this->paymentCondition = $days;
        return $this;
    }

}

class Test {
    /**
     * @param DateTime $dateInvoice
     * @param Config $config
     * @return DateTime
     */
    public function calcMaturityDate(\DateTime $dateInvoice, $config)
    {
        if ($config->getPaymentCondition() == 'delayed') {
            $dateMaturity = clone $dateInvoice;
            $startDay = $dateMaturity->format('j');

            $dateMaturity->modify("+{$config->getAmountDelayedDays()} days");
            $endDay = $dateMaturity->format('j');

            if ($startDay != $endDay && $endDay < 30) {
                $dateMaturity->modify('last day of last month');
            } else {
                $dateMaturity->modify('last day of this month');
            }
            if ($config->getPaymentDay() != 0) {
                $dateMaturity->modify('+' . $config->getPaymentDay() . 'days');
            }
            return $dateMaturity;
        } else {
            return $dateInvoice;
        }
    }
}

$config = new Config;
$config->setPaymentDay(15);
$config->setAmountDelayedDays(60);
$config->setPaymentCondition('delayed');

$test = new Test;
$date = $test->calcMaturityDate(new DateTime('2015-01-31'), $config);

var_dump($date);

?>

我必须从发票日期开始计算到期日。

如果我的发票日期为 2014-11-30 ,我的客户将配置为2个月后收费&amp;在15'(= 60天+15),我必须产生这样的成熟日期:

  

'2015-02-15'

为此,我需要在Config类中使用变量:

$config->getAmountDelayedDays()$config->getPaymentDay()

我的代码不能很好地处理所有问题。 2月改变年份,自定义价值的日子......跳月......

我认为问题在于

if ($startDay != $endDay && $endDay < 30) {
                $dateMaturity->modify('last day of last month');
            } else {
                $dateMaturity->modify('last day of this month');
            }

处理所有案件太简单了,也许是错的。我不清楚这个......

测试案例

我有单位测试测试这个功能我没有通过

/**
     * Tests MaturityDate
     * 
     */
    public function testCanGiveCorrectMaturityDate()
    {
        $config = $this->parser->setConfig();
        $config->setAmountDelayedDays(60);
        $config->setPaymentDay(15);
        $config->setPaymentCondition('delayed');

        // From February Ok ?
        $dateInvoice = new \Datetime('2015-02-28');
        $maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
        $this->assertEquals('15-05-2015', $maturityDate->format('d-m-Y'));

        // From February ok ?
        $dateInvoice = new \Datetime('2015-02-28');
        $config->setAmountDelayedDays(30);
        $config->setPaymentDay(0);
        $maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
        $this->assertEquals('31-03-2015', $maturityDate->format('d-m-Y'));

        // New years and pass february
        $config->setAmountDelayedDays(90);
        $config->setPaymentDay(15);
        $dateInvoice = new \Datetime('2014-11-30');
        $maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
        $this->assertEquals('15-03-2015', $maturityDate->format('d-m-Y'));

        // No delayed
        $config->setPaymentCondition('standard');
        $dateInvoice = new \Datetime('2014-11-30');
        $maturityDate = $this->mock->calcMaturityDate($dateInvoice , $config);
        $this->assertEquals('30-11-2014', $maturityDate->format('d-m-Y'));
    }

4 个答案:

答案 0 :(得分:2)

如果我做对了,您希望paymentDay始终是到期月份的第15天,或者是到期日晚于15日的下个月。

根据这个假设,你的课程将是:

public function calcMaturityDate(\DateTime $dateInvoice, $config)
{
        $dateMaturity = clone $dateInvoice;
        $dateMaturity->add(new \DateInterval("P{$config->getAmountDelayedDays()}D"));

        $payDay = $config->getPaymentDay();

        // patch 0 payDay to last day of month
        if (0 == $payDay) {
            $payDay = $dateMaturity->format('t');
        }

        if ($dateMaturity->format('j') > $payDay) {                
            $dateMaturity->modify('next month');                
        }
        $dateMaturity->setDate(
            $dateMaturity->format('Y'), 
            $dateMaturity->format('m'), 
            $payDay
        );

        return $dateMaturity;
}

很少注意到:

  • 班级名称有点误导,因为它返回付款日期,而不是到期日;
  • 成熟间隔为60天,而不是2个月;

对于最后一点,我建议重构您的配置类以返回\DateInterval的成熟时间间隔而不是整数,这样您就可以灵活地将2个月的间隔定义为"P2M"或60天{ {1}}取决于业务要求:
如果不是

"P60D"

你有

public function getAmountDelayedDays()
{
    return $this->amountDelayedDays;
}

上面的丑陋线

/**
* @return \DateInterval
*/ 
public function getDelayInterval()
{
    return $this->delayInterval;
}

变得优雅

$dateMaturity->add(new \DateInterval("P{$config->getAmountDelayedDays()}D"));

答案 1 :(得分:0)

在这些情况下,始终将“友好日期”转换为时间戳;算一算;然后转换回友好的约会。 像这样:

$invoice_date = "2014-11-30";
$ts_invoice_date = time($invoice_date);
$ts_maturity_month = $ts_invoice_date + (60*24*60*60); //60 days*24hrs*60mins*60secs
$maturity_date = date("Y-m-15 00:00:00", $ts_maturity_month);

答案 2 :(得分:0)

From documentation: Date and Time

date('Y-m-d', strtotime('+1 week'))

strtotime documentation

Your question:

I have to calculate a maturity date from the date of invoice.

You can use date('Y-m-d', strtotime('+60 days')) and that will handle odd/even number of days in month, as well as fix to hours (if you need that precision)..

A date 2014-11-30 with date('Y-m-d', strtotime('+ $amountDelayedDays days')) yelds the correct date.

答案 3 :(得分:0)

我想我得到了你想做的事情,我不得不做类似的事情。你基本上想要一些东西来确定当月的当天是否小于15,如果它仍然是本月的第15个,如果它说同月的20日那么日期是下个月的15日?我想这就是我读这个的方式。如果是这种情况,那么您需要将发票的日期与15日进行比较,如果小于同一个月,或者大于下个月。然后它变得有趣,因为你允许在到期日前5天的杠杆期。我使用过的一个因素。如果发票的日期是第14天并且您在15日设置了付款日期,则可能是这种情况。根据逻辑,客户只需要一天支付发票。我想我们去了15天零下5天。