我想显示数字如下
- 1为1,
- 2作为第二
- ...,
- 150至150。
如何为代码中的每个数字找到正确的序数后缀(st,nd,rd或th)?
我想显示数字如下
如何为代码中的每个数字找到正确的序数后缀(st,nd,rd或th)?
Answers:
$ends = array('th','st','nd','rd','th','th','th','th','th','th');
if (($number %100) >= 11 && ($number%100) <= 13)
$abbreviation = $number. 'th';
else
$abbreviation = $number. $ends[$number % 10];
$number
您要写的号码在哪里。适用于任何自然数。
作为功能:
function ordinal($number) {
$ends = array('th','st','nd','rd','th','th','th','th','th','th');
if ((($number % 100) >= 11) && (($number%100) <= 13))
return $number. 'th';
else
return $number. $ends[$number % 10];
}
//Example Usage
echo ordinal(100);
$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
PHP为此提供了内置功能。它甚至可以处理国际化!
$locale = 'en_US';
$nf = new NumberFormatter($locale, NumberFormatter::ORDINAL);
echo $nf->format($number);
请注意,此功能仅在PHP 5.3.0和更高版本中可用。
NumberFomatter file not found
。您是如何解决的?
apt-get install php5-intl
通过利用PHP内置的日期/时间函数中的类似功能,可以在一行中完成此操作。我谦虚地提交:
解:
function ordinalSuffix( $n )
{
return date('S',mktime(1,1,1,1,( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
}
详细说明:
内置date()
函数具有后缀逻辑,用于处理每月第n天的计算。当S
以格式字符串给出时,返回后缀:
date( 'S' , ? );
由于date()
需要的时间戳(对于?
以上),我们将通过我们的整数$n
作为day
参数mktime()
和使用假人值1
的hour
,minute
,second
,和month
:
date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );
实际上,对于一个月中某天(即$n > 31
)超出范围的值,这实际上会正常失败,但我们可以添加一些简单的内联逻辑以将上限设置$n
为29:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20))*10 + $n%10) ));
唯一的正值(2017年5月)失败的原因是$n == 0
,但通过在特殊情况下添加10可以轻松解决:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
更新,2017年5月
如@donatJ所观察到的那样,由于>=20
检查始终返回true ,因此上述结果在100以上(例如“ 111st”)失败。要在每个世纪重置这些值,我们在比较中添加一个过滤器:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n%100>=20)+($n==0))*10 + $n%10) ));
只需将其包装在一个函数中即可,以方便使用!
这里是单线:
$a = <yournumber>;
echo $a.substr(date('jS', mktime(0,0,0,1,($a%10==0?9:($a%100>20?$a%10:$a%100)),2000)),-2);
可能是最短的解决方案。当然可以用函数包装:
function ordinal($a) {
// return English ordinal number
return $a.substr(date('jS', mktime(0,0,0,1,($a%10==0?9:($a%100>20?$a%10:$a%100)),2000)),-2);
}
问候,保罗
EDIT1:11到13的代码更正。
EDIT2:111、211,...的代码更正
EDIT3:现在它也可以正常工作10的倍数。
来自http://www.phpro.org/examples/Ordinal-Suffix.html
<?php
/**
*
* @return number with ordinal suffix
*
* @param int $number
*
* @param int $ss Turn super script on/off
*
* @return string
*
*/
function ordinalSuffix($number, $ss=0)
{
/*** check for 11, 12, 13 ***/
if ($number % 100 > 10 && $number %100 < 14)
{
$os = 'th';
}
/*** check if number is zero ***/
elseif($number == 0)
{
$os = '';
}
else
{
/*** get the last digit ***/
$last = substr($number, -1, 1);
switch($last)
{
case "1":
$os = 'st';
break;
case "2":
$os = 'nd';
break;
case "3":
$os = 'rd';
break;
default:
$os = 'th';
}
}
/*** add super script ***/
$os = $ss==0 ? $os : '<sup>'.$os.'</sup>';
/*** return ***/
return $number.$os;
}
?>
我是为PHP4编写的。一切正常,而且非常经济。
function getOrdinalSuffix($number) {
$number = abs($number) % 100;
$lastChar = substr($number, -1, 1);
switch ($lastChar) {
case '1' : return ($number == '11') ? 'th' : 'st';
case '2' : return ($number == '12') ? 'th' : 'nd';
case '3' : return ($number == '13') ? 'th' : 'rd';
}
return 'th';
}
通常,您可以使用它并调用echo get_placing_string(100);。
<?php
function get_placing_string($placing){
$i=intval($placing%10);
$place=substr($placing,-2); //For 11,12,13 places
if($i==1 && $place!='11'){
return $placing.'st';
}
else if($i==2 && $place!='12'){
return $placing.'nd';
}
else if($i==3 && $place!='13'){
return $placing.'rd';
}
return $placing.'th';
}
?>
我制作了一个函数,该函数不依赖于PHP的date();
函数,因为它不是必需的,而且使它变得紧凑且尽可能短,因为我认为这是当前可能的。
代码:(总共121个字节)
function ordinal($i) { // PHP 5.2 and later
return($i.(($j=abs($i)%100)>10&&$j<14?'th':(($j%=10)>0&&$j<4?['st', 'nd', 'rd'][$j-1]:'th')));
}
下面的代码更紧凑。
它的工作方式如下:
printf("The %s hour.\n", ordinal(0)); // The 0th hour.
printf("The %s ossicle.\n", ordinal(1)); // The 1st ossicle.
printf("The %s cat.\n", ordinal(12)); // The 12th cat.
printf("The %s item.\n", ordinal(-23)); // The -23rd item.
关于此功能的知识:
floor($i)
,round($i)
或ceil($i)
在最后的return语句的开始)。format_number($i)
在最终return语句的开头添加以逗号分隔的整数(如果要显示成千上万个,等等)。$i
如果只想返回没有输入内容的序数后缀,则可以只从return语句的开头删除。该函数从2006年11月发布的PHP 5.2开始就完全起作用,这完全是由于数组语法较短。如果您之前有版本,请升级,因为您已经过时了将近十年!失败的话,只需将内联替换为['st', 'nd', 'rd']
包含以下内容的临时变量array('st', 'nd', 'rd');
。
相同的功能(不返回输入),但为了更好地理解我的短功能的分解图:
function ordinal($i) {
$j = abs($i); // make negatives into positives
$j = $j%100; // modulo 100; deal only with ones and tens; 0 through 99
if($j>10 && $j<14) // if $j is over 10, but below 14 (so we deal with 11 to 13)
return('th'); // always return 'th' for 11th, 13th, 62912th, etc.
$j = $j%10; // modulo 10; deal only with ones; 0 through 9
if($j==1) // 1st, 21st, 31st, 971st
return('st');
if($j==2) // 2nd, 22nd, 32nd, 582nd
return('nd'); //
if($j==3) // 3rd, 23rd, 33rd, 253rd
return('rd');
return('th'); // everything else will suffixed with 'th' including 0th
}
代码更新:
这是修改的版本,短14个完整字节(共107个字节):
function ordinal($i) {
return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');
}
或尽可能地短25个字节(总共96个字节):
function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
使用这最后一个函数,只需调用o(121);
,它将与我列出的其他函数完全相同。
代码更新2:
Ben和我一起工作,将其减少了38个字节(共83个字节):
function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
我们认为它不可能比这更短!但是愿意被证明是错误的。:)
希望大家喜欢。
abs()
模数%
abs();
消除了我需要的负号。
一个月中日期的更短版本(最多31个),而不是使用mktime()并且不需要pecl intl:
function ordinal($n) {
return (new DateTime('Jan '.$n))->format('jS');
}
或程序上:
echo date_format(date_create('Jan '.$n), 'jS');
这当然有效,因为我选择的默认月份(一月)为31天。
有趣的是,如果您在2月(或另一个不包含31天的月份)尝试使用,它将在结束之前重新启动:
...clip...
31st
1st
2nd
3rd
因此您可以使用t
循环中的日期说明符来计算本月的天数:当月的天数。
在PHP.net中找到答案
<?php
function ordinal($num)
{
// Special case "teenth"
if ( ($num / 10) % 10 != 1 )
{
// Handle 1st, 2nd, 3rd
switch( $num % 10 )
{
case 1: return $num . 'st';
case 2: return $num . 'nd';
case 3: return $num . 'rd';
}
}
// Everything else is "nth"
return $num . 'th';
}
?>
这是另一个使用日期函数的简短版本。它适用于任何数字(不受月份的天数限制),并考虑到* 11 * 12 * 13th不遵循* 1 * 2nd * 3rd格式。
function getOrdinal($n)
{
return $n . date_format(date_create('Jan ' . ($n % 100 < 20 ? $n % 20 : $n % 10)), 'S');
}
我喜欢这个小片段
<?php
function addOrdinalNumberSuffix($num) {
if (!in_array(($num % 100),array(11,12,13))){
switch ($num % 10) {
// Handle 1st, 2nd, 3rd
case 1: return $num.'st';
case 2: return $num.'nd';
case 3: return $num.'rd';
}
}
return $num.'th';
}
?>