PHP如何将营业时间数组转换为自然语言描述字符串
实现思路
你已经完成了按营业时间分组的核心逻辑,后续只需要4步即可生成符合阅读习惯的字符串:
- 第一步:提前定义星期映射表,包含「星期全名转缩写」「星期排序权重」两个映射,用来处理日期的格式化和连续段判断
- 第二步:对每个营业时间分组下的日期列表,先按星期顺序排序,再把连续的日期合并成「X to Y」的格式,不连续的单独保留
- 第三步:把同一分组下合并后的日期段用
and拼接成完整的日期前缀 - 第四步:把所有分组的「日期前缀: 时间段」用逗号拼接,得到最终结果
完整可运行代码
<?php // 定义星期映射:[全名 => [缩写, 排序权重]] $weekMap = [ 'monday' => ['mon', 1], 'tuesday' => ['tue', 2], 'wednesday' => ['wed', 3], 'thursday' => ['thu', 4], 'friday' => ['fri', 5], 'saturday' => ['sat', 6], 'sunday' => ['sun', 7] ]; $openHoursJson = '{"monday":{"working":"yes","open":"09:00","close":"17:00"},"tuesday":{"working":"yes","open":"09:00","close":"17:00"},"wednesday":{"working":"yes","open":"09:00","close":"17:00"},"thursday":{"working":"yes","open":"09:00","close":"18:00"},"friday":{"working":"yes","open":"09:00","close":"17:00"},"saturday":{"working":"yes","open":"09:00","close":"14:00"},"sunday":{"open":"00:00","close":"00:00"}}'; $openHoursArray = json_decode($openHoursJson, true); $openHoursReduced = []; foreach ($openHoursArray as $dayOfWeek => $dayConfigs) { if(!empty($dayConfigs['working']) && $dayConfigs['working'] == 'yes'){ $hoursStr = sprintf('%s to %s', $dayConfigs['open'], $dayConfigs['close']); $openHoursReduced[$hoursStr][] = $dayOfWeek; } } // 处理每个分组的日期拼接 $finalParts = []; foreach ($openHoursReduced as $hours => $dayList) { // 1. 给日期按周顺序排序 usort($dayList, function($a, $b) use ($weekMap) { return $weekMap[$a][1] - $weekMap[$b][1]; }); // 2. 合并连续日期段 $merged = []; $currentSegment = [$dayList[0]]; for ($i = 1; $i < count($dayList); $i++) { $prevWeight = $weekMap[$dayList[$i-1]][1]; $currentWeight = $weekMap[$dayList[$i]][1]; if ($currentWeight == $prevWeight + 1) { $currentSegment[] = $dayList[$i]; } else { $merged[] = $currentSegment; $currentSegment = [$dayList[$i]]; } } $merged[] = $currentSegment; // 3. 把合并后的段转成字符串 $segmentStrs = []; foreach ($merged as $seg) { if (count($seg) == 1) { $segmentStrs[] = $weekMap[$seg[0]][0]; } else { $segmentStrs[] = $weekMap[$seg[0]][0] . ' to ' . $weekMap[end($seg)][0]; } } $dayStr = implode(' and ', $segmentStrs); // 4. 拼装当前分组的完整描述 $finalParts[] = $dayStr . ': ' . $hours; } // 最终拼接所有分组 $result = implode(', ', $finalParts); echo $result; ?>
运行结果
输出完全符合你给出的预期:mon to wed and fri: 09:00 to 17:00, thu: 09:00 to 18:00, sat: 09:00 to 14:00
如果不需要and,把implode(' and ', $segmentStrs)改成implode(', ', $segmentStrs)即可。
内容的提问来源于stack exchange,提问作者endeavour
相关产品推荐
相关产品推荐

