我正在构建一个小班组合来计算学期开始的精确日期。决定学期开始的规则如下:
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()
函数,我宁愿不使用。
你说:
目标学期在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);
目标学期于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"));