0

我正在尝试制作一个接受此输入的函数: mon,tue,wed,thu,fri,sat

吐出这个: mon-sat

目前,我正在使用这个。

function dayrange($days){
   $days = explode(",", str_replace(" ","",$days));
   return reset($days) . "-" . end($days);
}

好的,现在对于曲线球,如果我给它这个字符串,我希望该函数也可以工作: mon,tue,wed,fri,sat

它需要跳过星期四并说如下内容:周一至周三,周五至周六

我可以获得有关最佳方法的建议吗?我正在使用 PHP,所以 php 中的答案很好,但伪代码也很好。

干杯

4

2 回答 2

3

基本上,我会通过以下方式解决这个问题:

  1. 将天数转换为相应的数值
  2. 将数字数组转换为具有范围的字符串
  3. 将字符串中的数字转换回星期几

我写了一些代码来做到这一点:

/**
 * Convert an array of numbers to a string containing ranges and single values
 * @param array $numbers an array of numbers
 * @return string
 */
function compressNumbers($numbers) {
    $result = array();
    sort($numbers);
    $previousValue = reset($numbers);
    $startValue = $previousValue;
    foreach ($numbers as $value) {
        if ($value > $previousValue + 1) {
            if ($startValue == $previousValue) {
                $result[] = $startValue;
            } else {        
                $result[] = $startValue . '-' . $previousValue;
            }
            $startValue = $value;
        }
        $previousValue = $value;
    }
    if ($startValue == $previousValue) {
        $result[] = $startValue;
    } else {        
        $result[] = $startValue . '-' . $previousValue;
    }
    return implode(',', $result);
}

/*
 * Creates an array with values the three letter representation for days of the 
 * week and keys the corresponding numeric representation.
 *
 * @return array
 */
function createLookupNumberToDay() {
    $date = strtotime('now');
    $lookup = array();
    for ($i = 1; $i <= 7; $i++) {
        $lookup[date('w', $date)] = date('D', $date);
        $date = strtotime('+1 day', $date);
    }
    return $lookup;
}

/*
 * Converts a string listing days separated by commas into 
 * an array with values the numeric value for the corresponding
 * day of the week.
 *
 * @param string $days
 * @return array
 */
function convertDaysToNumbers($days) {
    $result = array();
    $daysArray = explode(",", str_replace(" ","",$days));
    foreach ($daysArray as $day) {
        $result[] = date('w', strtotime($day));
    }
    return $result;
}

/*
 * Converts the numbers in a string to the corresponding 3-letter day of the
 * week abbreviation.
 *
 * @param string $string
 * @return string
 */
function convertNumbersToDays($string) {
    $lookup = createLookupNumberToDay();
    return str_replace(array_keys($lookup), $lookup, $string);
}

function convert($string) {
    return (convertNumbersToDays(compressNumbers(convertDaysToNumbers($string))));
}

echo convert('mon,tue,wed,thu,fri,sat');
echo '<br />';
echo convert('mon,tue,wed,sat');
echo '<br />';
于 2011-05-10T05:11:32.530 回答
1

尚未对此进行测试,但应该会给您一个良好的开端。它也处理周包装。

function dayrange($days){
    $wdays = array("mon","tue","wed","thu","fri","sat","sun");

    $indays = explode(",", str_replace(" ","",$days)); // expand the list to an array


    $retstr = array_shift($indays); // get the first date

    $curpos = array_search($retstr, $wdays);  // current position in the wdays array
    $intv = 0;    // interval between days to avoid mon-tue like output

    foreach($indays as $d) {
       if($d == $wdays[$curpos]) {
          $curpos = ($curpos++) % 7; // this will take care of wrapping.
          $intv++;
       } else {
           $retstr.= ($intv > 1 ? "-".$d:",".$d); // use appropriate join
           $intv = 0; // reset interval
       }
    }
    if($intv > 0) {   // if anything was left deal with the end.
        $retstr.= ($intv > 1 ? "-".$d:",".$d);
    } else {
        $retstr.= ",".$d;
    }
    return ($retstr);
}
于 2011-05-10T04:35:37.107 回答