天数到期间
Days Array to Periods
我有一组类似于以下的天数:
array(10) {
[0]=>
string(8) "01/06/18"
[1]=>
string(8) "02/06/18"
[2]=>
string(8) "03/06/18"
[3]=>
string(8) "11/06/18"
[4]=>
string(8) "12/06/18"
[5]=>
string(8) "13/06/18"
[6]=>
string(8) "14/06/18"
[7]=>
string(8) "15/06/18"
[8]=>
string(8) "16/06/18"
[9]=>
string(8) "20/06/18"
}
我正在尝试解决方案,以便通过以下方式从一系列天数中获取经期:
Period 1:
01/06/18 - 03/06/18
Period 2:
11/06/18 - 16/06/18
Period 3:
20/06/18 - 20/06/18
最短的路是什么!?
这是我正在尝试但没有成功的方法:
注意:我正在更改日期格式以符合 Y-m-d
private function SetPeriods($days)
{
// check if input is empty
if(count($days) == 0) return array();
// output to fill
$ranges = array();
// order dates keys in order to have the first date in temporary order
ksort($days);
// get first and last day
$firstday = key($days);
end($days);
$lastday = key($days);
// get the type of first day (actually the current day where we looks)
$current_type = $days[$firstday];
// using datetime object for easy step of 1 day
$datetime = new DateTime($days[$firstday]);
$datetime->setTime(9,0,0); // avoid time problems at midnight (it's needed?)
// do the first step outside the while
$datetime->add(new DateInterval('P1D'));
// store old value of day
$oldday = $firstday;
// build the first range
$ranges[] = array($firstday,null,$current_type);
while(($day = $datetime->format('Y-m-d')) <= $lastday) {
// if there are holes, fill it with null
if(!isset($days[$day])) {
$days[$day] = null;
}
// check if type has changed (=>need new range)
if(($days[$day] !== $current_type)) {
$ranges[count($ranges)-1][1] = $oldday;
$ranges[] = array($day,null,$days[$day]);
$current_type = $days[$day];
}
// store previous day
$oldday = $day;
// next day
$datetime->add(new DateInterval('P1D'));
}
// complete the last range
$ranges[count($ranges)-1][1] = $lastday;
// remove range of holes
foreach($ranges as $k=>$range) {
if(is_null($range[2])) {
unset($ranges[$k]);
}
}
return $ranges;
}
问题是现在我只有一个约会我不知道是什么问题无法弄清楚
这是一种方法,不知道是不是最短的。
我转换为 Unix 时间,如果 Unix 时间与以前的 Unix 时间相比超过一天,我会创建一个新的子数组来存储它。
然后 res 数组将保存 Unix 时间段。
我遍历它并转换为仅获取最小值和最大值的日期。
$i =-1;
$prev =0;
$format = "d/m/y";
Foreach($arr as $val){
$dt = date_create_from_format ($format , $val);
$unix = date_timestamp_get($dt);
If($unix -$prev > 86400) $i++;
$res[$i][] = $unix;
$prev = $unix;
}
Foreach($res as $period){
If(count($period) >1){
$periods[] = date($format, min($period)) . " - " . date($format, max($period));
}Else{
$periods[] = date($format, min($period));
}
}
Var_dump($periods);
现在想想还可以再短一点
我跳过了最后一个 foreach,因为我可以在主循环中即时执行它,除了循环之后完成的最后一项。
$i =-1;
$prev =0;
$format = "d/m/y";
Foreach($arr as $val){
$dt = date_create_from_format ($format , $val);
$unix = date_timestamp_get($dt);
If($unix -$prev > 86400){
$i++;
If($i>0){
If(count($res[$i-1]) >1){
$periods[] = date($format, min($res[$i-1])) . " - " . date($format, max($res[$i-1]));
}Else{
$periods[] = date($format, min($res[$i-1]));
}
}
}
$res[$i][] = $unix;
$prev = $unix;
}
If(count(end($res)) >1){
$periods[] = date($format, min(end($res))) . " - " . date($format, max(end($res)));
}Else{
$periods[] = date($format, min(end($res)));
}
Var_dump($periods);
此逻辑基于 10 天周期 1-9,10-19,20-31
$daysArray = array(
0=> "01/06/18",
1=> "02/06/18",
2=> "03/06/18",
3=> "11/06/18",
4=> "12/06/18",
5=> "13/06/18",
6=> "14/06/18",
7=> "15/06/18",
8=> "16/06/18",
9=> "20/06/18"
);
$daysArray1 = $daysArray2 = $daysArray3 = array();
foreach ($daysArray as $key=>$value) {
$expValue = $value;
$val = explode('/',$expValue);
if($val[0]<9) {
$daysArray1[] = $value;
}
if($val[0]>9 && $val[0]<19) {
$daysArray2[] = $value;
}
if($val[0]>19 && $val[0]<=31) {
$daysArray3[] = $value;
}
}
echo 'Period 1: <br />';
echo min(array_values($daysArray1)).'-'.max(array_values($daysArray1));
echo '<br /> Period 2: <br />';
echo min(array_values($daysArray2)).'-'.max(array_values($daysArray2));
echo '<br /> Period 3: <br />';
echo min(array_values($daysArray3)).'-'.max(array_values($daysArray3));
我有一组类似于以下的天数:
array(10) {
[0]=>
string(8) "01/06/18"
[1]=>
string(8) "02/06/18"
[2]=>
string(8) "03/06/18"
[3]=>
string(8) "11/06/18"
[4]=>
string(8) "12/06/18"
[5]=>
string(8) "13/06/18"
[6]=>
string(8) "14/06/18"
[7]=>
string(8) "15/06/18"
[8]=>
string(8) "16/06/18"
[9]=>
string(8) "20/06/18"
}
我正在尝试解决方案,以便通过以下方式从一系列天数中获取经期:
Period 1:
01/06/18 - 03/06/18
Period 2:
11/06/18 - 16/06/18
Period 3:
20/06/18 - 20/06/18
最短的路是什么!?
这是我正在尝试但没有成功的方法:
注意:我正在更改日期格式以符合 Y-m-d
private function SetPeriods($days)
{
// check if input is empty
if(count($days) == 0) return array();
// output to fill
$ranges = array();
// order dates keys in order to have the first date in temporary order
ksort($days);
// get first and last day
$firstday = key($days);
end($days);
$lastday = key($days);
// get the type of first day (actually the current day where we looks)
$current_type = $days[$firstday];
// using datetime object for easy step of 1 day
$datetime = new DateTime($days[$firstday]);
$datetime->setTime(9,0,0); // avoid time problems at midnight (it's needed?)
// do the first step outside the while
$datetime->add(new DateInterval('P1D'));
// store old value of day
$oldday = $firstday;
// build the first range
$ranges[] = array($firstday,null,$current_type);
while(($day = $datetime->format('Y-m-d')) <= $lastday) {
// if there are holes, fill it with null
if(!isset($days[$day])) {
$days[$day] = null;
}
// check if type has changed (=>need new range)
if(($days[$day] !== $current_type)) {
$ranges[count($ranges)-1][1] = $oldday;
$ranges[] = array($day,null,$days[$day]);
$current_type = $days[$day];
}
// store previous day
$oldday = $day;
// next day
$datetime->add(new DateInterval('P1D'));
}
// complete the last range
$ranges[count($ranges)-1][1] = $lastday;
// remove range of holes
foreach($ranges as $k=>$range) {
if(is_null($range[2])) {
unset($ranges[$k]);
}
}
return $ranges;
}
问题是现在我只有一个约会我不知道是什么问题无法弄清楚
这是一种方法,不知道是不是最短的。
我转换为 Unix 时间,如果 Unix 时间与以前的 Unix 时间相比超过一天,我会创建一个新的子数组来存储它。
然后 res 数组将保存 Unix 时间段。
我遍历它并转换为仅获取最小值和最大值的日期。
$i =-1;
$prev =0;
$format = "d/m/y";
Foreach($arr as $val){
$dt = date_create_from_format ($format , $val);
$unix = date_timestamp_get($dt);
If($unix -$prev > 86400) $i++;
$res[$i][] = $unix;
$prev = $unix;
}
Foreach($res as $period){
If(count($period) >1){
$periods[] = date($format, min($period)) . " - " . date($format, max($period));
}Else{
$periods[] = date($format, min($period));
}
}
Var_dump($periods);
现在想想还可以再短一点
我跳过了最后一个 foreach,因为我可以在主循环中即时执行它,除了循环之后完成的最后一项。
$i =-1;
$prev =0;
$format = "d/m/y";
Foreach($arr as $val){
$dt = date_create_from_format ($format , $val);
$unix = date_timestamp_get($dt);
If($unix -$prev > 86400){
$i++;
If($i>0){
If(count($res[$i-1]) >1){
$periods[] = date($format, min($res[$i-1])) . " - " . date($format, max($res[$i-1]));
}Else{
$periods[] = date($format, min($res[$i-1]));
}
}
}
$res[$i][] = $unix;
$prev = $unix;
}
If(count(end($res)) >1){
$periods[] = date($format, min(end($res))) . " - " . date($format, max(end($res)));
}Else{
$periods[] = date($format, min(end($res)));
}
Var_dump($periods);
此逻辑基于 10 天周期 1-9,10-19,20-31
$daysArray = array(
0=> "01/06/18",
1=> "02/06/18",
2=> "03/06/18",
3=> "11/06/18",
4=> "12/06/18",
5=> "13/06/18",
6=> "14/06/18",
7=> "15/06/18",
8=> "16/06/18",
9=> "20/06/18"
);
$daysArray1 = $daysArray2 = $daysArray3 = array();
foreach ($daysArray as $key=>$value) {
$expValue = $value;
$val = explode('/',$expValue);
if($val[0]<9) {
$daysArray1[] = $value;
}
if($val[0]>9 && $val[0]<19) {
$daysArray2[] = $value;
}
if($val[0]>19 && $val[0]<=31) {
$daysArray3[] = $value;
}
}
echo 'Period 1: <br />';
echo min(array_values($daysArray1)).'-'.max(array_values($daysArray1));
echo '<br /> Period 2: <br />';
echo min(array_values($daysArray2)).'-'.max(array_values($daysArray2));
echo '<br /> Period 3: <br />';
echo min(array_values($daysArray3)).'-'.max(array_values($daysArray3));