动态日期定义和条件

时间:2011-09-16 15:48:42

标签: php date

我正在建立一个小班组合来计算一个学期开始的确切日期。确定学期开始的规则如下:

The monday of week number ## and after dd-mm-yyyy date

ie: for winter its week number 2 and it must be after the january 8th of that year

我正在构建一个包含所有学期这些数据的资源类(总共4个)。但现在我面临一个基于public holidays的问题。由于其中一些可能在星期一,在那些情况下我需要得到星期二的日期。

我目前正在处理的问题如下:

The target semester begins on or after august 30 and must be on week 35. 

我还必须考虑到9月的第一个星期一发生的公众假期。

PHP术语中的条件如下

if (date('m', myDate) == 9 // if the month is september
    && date('w', myDate) == 1 // if the day of the week is monday
    && date('d', myDate) < 7 // if we are in the first 7 days of september
)

将此作为一个条件并将其存储在数组中的最佳方式是什么?

修改

我可能不够清楚,发现日期不是问题。实际问题是在配置数组中存储一个如下所示的条件:

$_ressources = array(
    1 => array(
        'dateMin' => '08-01-%',
        'weekNumber' => 2,
        'name' => 'Winter',
        'conditions' => array()
    ),
    2 => array(
        'dateMin' => '30-04-%',
        'weekNumber' => 18,
        'name' => 'Spring',
        'conditions' => array()
    ),
    3 => array(
        'dateMin' => '02-07-%',
        'weekNumber' => 27,
        'name' => 'Summer',
        'conditions' => array()
    ),
    4 => array(
        'dateMin' => '30-08-%',
        'weekNumber' => 35,
        'name' => 'Autumn',
        'conditions' => array("date('m', %date%) == 9  && date('w', %date%) == 1 && date('d', %date%) < 7")
    )
);

我现在遇到的问题是,我将不得不使用eval()函数,我宁愿不这样做。

2 个答案:

答案 0 :(得分:1)

  

目标学期在8月30日或之后开始,必须在第35周

该学期的开始是第35周至8月30日之间的最短日期:

$week35 = new DateTime("January 1 + 35 weeks");
$august30 = new DateTime("August 30");

$start = min($week35, $august30);

可替换地:

$start = min(date_create("January 1 + 52 weeks"), date_create("August 30"));

答案 1 :(得分:1)

你说:

  

目标学期在8月30日或之后开始,必须在第35周。

如果是这种情况,您可以简单地检查周数。

if(date('W', myDate) == 35)

或者,如果您的测试条件正确,那么您应该将日期编号比较为7,从1开始。

if((date('m', myDate) == 9 // september
    && date('w', myDate) == 1 // monday
    && date('d', myDate) <= 7 // first 7 days of september
)

然后在if语句中,一旦你找到星期一,如果它不是公众假期就行,那就这样做

if(...){
    while(!array_search (myDate, aray_of_public_holidays))
        date_add($myDate, date_interval_create_from_date_string('1 days'));
}

此处array_of_public_holidays包含公众假期列表。

使用代码更新
以下代码应该适用于您的目的

<?php
    // array with public holidays
    $public_holidays = array(/* public holidays */);

    // start on 30th august
    $myDate = new DateTime('August 30');

    // loop till week number does not cross 35
    while($myDate->format('W') <= 35){
        // if its a monday
        if($myDate->format('w') == 1){
            // find the next date not a public holiday
            while(array_search($myDate, $public_holidays))
                $myDate->add(date_interval_create_from_date_string('1 days'));

            // now myDate stores the valid semester start date so exit loop
            break;
        }
        // next date
        $myDate->add(date_interval_create_from_date_string('1 days'));
    }

    // now myDate is the semester start date
?>

根据更新的问题更新
以下代码应该可以满足您的需求。您不需要将条件作为PHP代码存储在数组中。以下代码显示了如何完成

// semester conditions
$sem_conditions = array(
    1 => array(
        'dateMin' => '08-01-%',
        'weekNumber' => 2,
        'name' => 'Winter'
    ),
    2 => array(
        'dateMin' => '30-04-%',
        'weekNumber' => 18,
        'name' => 'Spring'
    ),
    3 => array(
        'dateMin' => '02-07-%',
        'weekNumber' => 27,
        'name' => 'Summer'
    ),
    4 => array(
        'dateMin' => '30-08-%',
        'weekNumber' => 35,
        'name' => 'Autumn'
    )
);

// array with public holidays format (d-M)
$public_holidays = array('05-09', '10-01');

// store sem starts
$sem_starts = array();

// for each semester
foreach($sem_conditions as $sem){
    // start date
    $myDate = date_create_from_format('d-m', substr($sem['dateMin'], 0, -2));

    // loop till week number does not cross $sem['weekNumber']
    while($myDate->format('W') <= $sem['weekNumber']){
        // if its a monday
        if($myDate->format('w') == 1){
            // find the next date not a public holiday
            while(array_search($myDate->format('d-m'), $public_holidays) !== false)
                $myDate->add(date_interval_create_from_date_string('1 days'));

            // now myDate stores the valid semester start date so exit loop
            break;
        }
        // next date
        $myDate->add(date_interval_create_from_date_string('1 days'));
    }

    // add to sem starts
    $sem_start[$sem['name']] = $myDate->format('d-m-Y');
}

var_dump($sem_start);