如何按特定复数规则处理经过时间的三种本地化表述?
解决PHP时间差本地化复数规则的问题
要让time_elapsed_string函数符合你指定的复数规则,核心是替换原函数中仅区分"1"和"大于1"的判断逻辑,改为根据数值范围选择对应复数形式的逻辑。
修改后的完整函数
<?php function time_elapsed_string($datetime, $full = false) { $now = new DateTime; $ago = new DateTime($datetime); $diff = $now->diff($ago); $diff->w = floor($diff->d / 7); $diff->d -= $diff->w * 7; $periods = array( 'y' => ['godinu', 'godine', 'godina'], 'm' => ['mesec', 'meseca', 'meseci'], 'w' => ['nedelju', 'nedelje', 'nedelja'], 'd' => ['dan', 'dana', 'dana'], 'h' => ['sat', 'sata', 'sati'], 'i' => ['minut', 'minuta', 'minuta'], 's' => ['sekund', 'sekunde', 'sekundi'] ); $parts = array(); foreach ($periods as $k => &$v) { $count = $diff->$k; if ($count) { // 根据数值选择对应的复数索引 $index = match(true) { $count === 1 => 0, $count >= 2 && $count <=4 => 1, default => 2 }; $parts[] = $count . ' ' . $v[$index]; } } if (!$full) $parts = array_slice($parts, 0, 1); return $parts ? 'pre ' . implode(', ', $parts) : DATE_NOW; } ?>
关键修改说明
复数形式判断逻辑:
用match(true)结构(PHP 8+支持)精准匹配数值范围:- 数量为
1时,取$periods数组第0个元素(单数形式) - 数量在
2-4之间时,取第1个元素(中间复数形式) - 数量大于4时,取第2个元素(通用复数形式)
若你的PHP版本低于8,可替换为嵌套三元运算符:
$index = $count === 1 ? 0 : ($count >=2 && $count <=4 ? 1 : 2);- 数量为
兼容两类单位规则:
对于day(d)、minute(i)这类仅需两种形式的单位,$periods数组中第1和第2个元素已设为相同值,判断逻辑无需额外调整即可自动适配。
效果验证
- 1年:
1 godinu - 3年:
3 godine - 5年:
5 godina - 1天:
1 dan - 2天:
2 dana - 1小时:
1 sat - 4小时:
4 sata - 6小时:
6 sati
内容的提问来源于stack exchange,提问作者Monk
相关产品推荐
相关产品推荐

