我有一系列的活动表现日期,例如:
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表演因为需要单独处理而引起额外的复杂化。
答案 0 :(得分:1)
我们将字符串转换为array_map和strtotime的时间戳,然后将数组中连续的元素组合在一起,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);
20th-23rd Jan 8pm, 25th-26th Jan 8pm, 31st Jan-1st Feb 8pm
输出不包括22nd Jan 2pm
,但它应该很容易修改函数以获得所需的输出(提示:检查是否date('G')
&gt; 12来知道时间是否为那天是下午。)