我正在建立一个小班组合来计算一个学期开始的确切日期。确定学期开始的规则如下:
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()
函数,我宁愿不这样做。
答案 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);