将一组php日期转换为简单的人类可读字符串

时间:2014-01-19 16:39:49

标签: php arrays date

我有一系列的活动表现日期,例如:

2014-01-20 20:00:00
2014-01-21 20:00:00
2014-01-22 14:00:00
2014-01-22 20:00:00
2014-01-23 20:00:00
2014-01-25 20:00:00
2014-01-26 20:00:00
2014-01-31 20:00:00
2014-02-01 20:00:00

在php中是否有一种简单的方法可以将其转换为人类可读的字符串,例如;

20th-23rd Jan 8pm, 22nd Jan 2pm, 25th-26th Jan 8pm, 31st Jan - 1st Feb 8pm

请注意,数组始终采用日期时间顺序,但不一定是连续的。 Matinee表演因为需要单独处理而引起额外的复杂化。

5 个答案:

答案 0 :(得分:1)

我们将字符串转换为array_mapstrtotime的时间戳,然后将数组中连续的元素组合在一起,Arithmetic Progression中的公共区别=​​ 86400(因为86400)秒= 1天):

$arr = array(
    "2014-01-20 20:00:00",
    "2014-01-21 20:00:00",
    "2014-01-22 14:00:00",
    "2014-01-22 20:00:00",
    "2014-01-23 20:00:00",
    "2014-01-25 20:00:00",
    "2014-01-26 20:00:00",
    "2014-01-31 20:00:00",
    "2014-02-01 20:00:00"
);
$arr = array_map("strtotime", $arr);
$_arr = array();
$size = sizeof($arr);
$val = $arr[0];
for($i = 0; $i < $size; $i++){
    if(!array_key_exists($i+1, $arr) || $arr[$i+1]-$arr[$i] != 86400){
    $d1 = date("jS", $val);
    $d2 = date("jS", $arr[$i]);
    $m1 = date("M", $val);
    $m2 = date("M", $arr[$i]);
    $t = date("ga", $val);
        if($m1 == $m2){
            if($d1 == $d2){
            $_arr[] = $d1." ".$m1." ".$t;
            }
            else{
            $_arr[] = $d1."-".$d2." ".$m1." ".$t;
            }
        }
        else{
        $_arr[] = $d1." ".$m1."-".$d2." ".$m2." ".$t;
        }
        if(array_key_exists($i+1, $arr)){
        $val = $arr[$i+1];
        }
    }
}
print(implode(", ", $_arr));

输出将是:

  1月20日至21日1月8日,1月22日下午2点,1月22日至23日,下午8点,1月25日 - 26日,下午8点,1月31日 - 2月1日晚上8点

查看工作中的代码here

答案 1 :(得分:0)

您可以遍历每一行并创建一个新的人类可读时间戳数组,如下所示:

$new_array[] = date("D d M", strtotime($current_line));

显然将输出的格式更改为您选择的格式(http://www.php.net/manual/en/function.date.php

答案 2 :(得分:0)

您的预期输出:

20th-23rd Jan 8pm, 22nd Jan 2pm, 25th-26th Jan 8pm, 31st Jan - 1st Feb 8pm

我认为似乎不可能在输出中没有序列或没有模式。你应该有逻辑模式。

现场演示:https://eval.in/91823
试试这个:

$str = "2014-01-21 20:00:00";
echo date("dS M g:i a", strtotime($str));

输出:

21st Jan 8:00 pm

对于数组: 演示:https://eval.in/91834

$arr = array("2014-01-20 20:00:00",
"2014-01-21 20:00:00",
"2014-01-22 14:00:00",
"2014-01-22 20:00:00",
"2014-01-23 20:00:00",
"2014-01-25 20:00:00",
"2014-01-26 20:00:00",
"2014-01-31 20:00:00",
"2014-02-01 20:00:00");
foreach($arr as $a )
{

echo date("dS M ga", strtotime($a))."\n";
}

输出:

20th Jan 8pm
21st Jan 8pm
22nd Jan 2pm
22nd Jan 8pm
23rd Jan 8pm
25th Jan 8pm
26th Jan 8pm
31st Jan 8pm
01st Feb 8pm

答案 3 :(得分:0)

我认为Sharanya的回答可能是最优雅的解决方案,尽管我会分享我自己想出的内容。

基本逻辑是创建一个临时工作数组来保存日期范围,包括开始日期和结束日期加上演奏时间。然后我循环遍历日期数组并在结束日期不是当前日期的1天或时间不匹配时添加到数组中。

$dates = array("2014-01-20 20:00:00","2014-01-21 20:00:00","2014-01-22 14:00:00","2014-01-22 20:00:00","2014-01-23 20:00:00","2014-01-25 20:00:00","2014-01-26 20:00:00","2014-01-31 20:00:00","2014-02-01 20:00:00");

$workingarray = array('start' => array(), 'end' => array(), 'time' => array());

// Loop through the results 
foreach($dates as $date) {
    // Check to see if there's a match at this time already
    $key = reverse_search(date("ga", strtotime($date)), $workingarray['time']);
    if($key===false) {
        $workingarray['start'][] = $date;
        $workingarray['end'][] = $date;
        $workingarray['time'][] = date("ga", strtotime($date));
    } else {
        // Check to see if the end date of this performance is exactly one day less
        if($workingarray['end'][$key]==date("Y-m-d H:i:s", strtotime('-1 day', strtotime($date)))) {
            $workingarray['end'][$key] = $date;
        } else {
            $workingarray['start'][] = $date;
            $workingarray['end'][] = $date;
            $workingarray['time'][] = date("ga", strtotime($date));
        }
    }
}

// All the ranges are now in the $workingarray array, so just need to assemble them
$datesarray = array();
for($n = 0; $n <= count($workingarray); $n++) {
    // Handle situations where range spans different months
    if(date("m", strtotime($workingarray['start'][$n]))==date("m", strtotime($workingarray['end'][$n]))) {
        $startstr = date("jS - ", strtotime($workingarray['start'][$n]));
    } else {
        $startstr = date("jS M - ", strtotime($workingarray['start'][$n]));
    }
    // Handle situations where performance is only on one day
    if($workingarray['start'][$n]==$workingarray['end'][$n]) {
        $startstr = "";
    }
    $endstr = date("jS M ", strtotime($workingarray['end'][$n]));
    $timestr = $workingarray['time'][$n];
    $datesarray[] = $startstr.$endstr.$timestr;
}
// Glue the array together as one string
$datestring = implode(", ", $datesarray);
echo $datestring;

// Function to find last matching key as array_search will only find the first one
function reverse_search($value, $array) {
    $found = FALSE;
    foreach($array as $key => $item) {
        if($item==$value) {
            $found = $key;
        }
    }
    return $found;
}

答案 4 :(得分:0)

我写了一个泛型函数,它接受一个日期字符串数组并将它们转换为人类可读的日期范围。请注意,它使用了DateTime类,默认情况下在PHP =&gt;中可用。 5.2.0。

首先,使用array_map()创建一个时间戳数组,其中strtotime作为回调函数。现在遍历结果数组并确定范围的结束。为此,我们使用while循环。

while (isset($tsArr[$i+1]) && ($tsArr[$i+1]-$tsArr[$i]) / (60*60) <= 24) {
    $rend = $tsArr[++$i];
}

我们检查当前时间戳和下一个时间戳之间的小时数是否大于24,如果是,则更新$rend变量。在最后一次迭代中,$rend将包含范围结束的时间戳。

这是完整的功能:

function getDateRanges($dates) {        
    $tsArr = array_map('strtotime', $dates);
    $ranges = array();

    for ($i=0, $len = count($tsArr); $i < $len; $i++) {     

        $rstart = $tsArr[$i];
        $rend = $rstart;

        // determine the end of the range
        while (isset($tsArr[$i+1]) && ($tsArr[$i+1]-$tsArr[$i]) / (60*60) <= 24) {
            $rend = $tsArr[++$i];
        }

        // create DateTime objects to work with dates
        $startDate = new DateTime('@'.$rstart);
        $endDate = new DateTime('@'.$rend);

        // get date start and last day of month
        $start = $startDate->format('j');
        $lastDay = $startDate->format('t');

        // if last day of month, append month name
        if ($start == $lastDay)
            $start = $startDate->format('jS M');
        else 
            $start = $startDate->format('jS');

        // end date
        $end = $endDate->format('jS M ga');

        $ranges[] = $start.'-'.$end;
    }
    return $ranges;
}

可以使用如下:

$arr = getDateRanges($dates);
echo implode(', ', $arr);

Output

20th-23rd Jan 8pm, 25th-26th Jan 8pm, 31st Jan-1st Feb 8pm

输出不包括22nd Jan 2pm,但它应该很容易修改函数以获得所需的输出(提示:检查是否date('G')&gt; 12来知道时间是否为那天是下午。)