更好的代码结构?

时间:2015-11-06 13:09:18

标签: php datetime

所以,我有这个要求:

给定日期($dateissued)是一个字符串,通常是DD.MM.YYYY,但它也可以是MM.YYYY,甚至只是YYYY。在后一种情况下,我应该将其视为一个区间,例如" 2005年11月和#34; for" 11.2005"。为此,我输出到$startdate,如果是一个间隔,则设置$enddate(否则返回空)。输出进入JSON,因此格式化很好。

  • 如果给定日期为XX.XX.XXXX,则解析为DD.MM.YYYY
  • 如果给定日期为XX.XXXX,则解析为01.MM.YYYY,并将endDate设置为LL.MM.YYYY,其中LL是月中的最后一天
  • 如果给定日期为XXXX,则解析为01.01.YYYY,并将endDate设置为31.12.YYYY

        $dateissued = get_sub_field('w_pub_dateissued'); // get Date String from field
        $parsedstartdate = date_create_from_format('d.m.Y', $dateissued );
        $startdate = '';
        $enddate = '';
        if ($parsedstartdate == false ) { // date_create_from_format() returns false if it fails
            $parsedstartdate = date_create_from_format('d.m.Y', '01.'.$dateissued ); // try again as 01.MM.YYYY
            if ($parsedstartdate == false ) {
                $parsedstartdate = date_create_from_format('d.m.Y', '01.01.'.$dateissued ); // try again as 01.01.YYYY
                if ($parsedstartdate == false ) {
                    // bad date; nothing todo, $startdate is empty by default
                } else {
                    // Full Year
                    $startdate = $parsedstartdate->format('d.m.Y');
                    $parsedenddate = clone $parsedstartdate;
                    $parsedenddate->add( new DateInterval('P1Y') )->sub( new DateInterval('P1D'));
                    $enddate = $parsedenddate->format('d.m.Y');
                }
            } else {
                // Full Month
                $startdate = $parsedstartdate->format('d.m.Y');
                $parsedenddate = clone $parsedstartdate;
                $parsedenddate->add( new DateInterval('P1M') )->sub( new DateInterval('P1D'));
                $enddate = $parsedenddate->format('d.m.Y');
            }
        } else {
            $startdate = $parsedstartdate->format('d.m.Y');
        }
        return compact('startdate', 'enddate');
    

我对此代码的反对意见:

  • 重复
  • 嵌套if-loops
  • 一般很难掌握逻辑

所以,亲爱的社区 - 我怎么能让这更好?你会做什么?

1 个答案:

答案 0 :(得分:1)

我认为我们可以做点像......

<?php
function get_date_interval($thisdate){
    /* I don't have the function you do so here we are receiving date as parameter */
    $dateissued = $thisdate;
    $return=false;
    if($parsedstartdate=date_create_from_format('d.m.Y',substr('01.01.'.$dateissued,-10))){
        switch (strlen($dateissued)){
            case 4:
                $interval = 'P1Y';
                break;
            case 7:
                $interval = 'P1M';      
                break;
            case 10:    
                $interval = 'P1D';
                break;
            default:
                return $return;
        }        
        $startdate = $parsedstartdate->format('d.m.Y');
        $parsedenddate = clone $parsedstartdate;
        $parsedenddate->add( new DateInterval($interval) )->sub( new DateInterval('P1D'));
        $enddate = $parsedenddate->format('d.m.Y');
        $return = compact('startdate', 'enddate');
    }
    return $return;
}

...测试

echo "<pre>";
print_r(get_date_interval('2015'));
print_r(get_date_interval('11.2015'));
print_r(get_date_interval('06.11.2015')) ;
print_r(get_date_interval('invalid')) ;
print_r(get_date_interval('15')) ;
print_r(get_date_interval(NULL)) ;
echo "</pre>";

我故意将您的规格改为我的口味,因为当一天的范围我开始日期和结束日期都具有相同的日期时...所以输出将是:

Array
(
    [startdate] => 01.01.2015
    [enddate] => 31.12.2015
)
Array
(
    [startdate] => 01.11.2015
    [enddate] => 30.11.2015
)
Array
(
    [startdate] => 06.11.2015
    [enddate] => 06.11.2015
)

但是,如果这会影响现有的逻辑/流程,我们只需要另一个如果使其成为= false