修改:
我不是母语为英语的人。对于那个很抱歉。我认为我们能做的最好的事情就是定义到期日。
到期日是指示付款截止日期的日期 发票在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'));
}
答案 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;
}
很少注意到:
对于最后一点,我建议重构您的配置类以返回\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'))
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天。