在 PHP 中显示带有序数后缀的数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3109978/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 08:42:39  来源:igfitidea点击:

Display numbers with ordinal suffix in PHP

phpnumbers

提问by ArK

I want to display numbers as follows

我想显示数字如下

  • 1 as 1st,
  • 2 as 2nd,
  • ...,
  • 150 as 150th.
  • 1 为 1,
  • 2 作为 2,
  • ...,
  • 150 为 150。

How should I find the correct ordinal suffix (st, nd, rd or th) for each number in my code?

我应该如何为代码中的每个数字找到正确的序数后缀(st、nd、rd 或 th)?

回答by Iacopo

from wikipedia:

来自维基百科

$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];

Where $numberis the number you want to write. Works with any natural number.

$number你想写的数字在哪里。适用于任何自然数。

As a function:

作为一个函数:

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);

回答by Jeremy Kauffman

PHP has built-in functionality for this. It even handles internationalization!

PHP 具有为此的内置功能。它甚至可以处理国际化!

$locale = 'en_US';
$nf = new NumberFormatter($locale, NumberFormatter::ORDINAL);
echo $nf->format($number);

Note that this functionality is only available in PHP 5.3.0 and later.

请注意,此功能仅在 PHP 5.3.0 及更高版本中可用。

回答by Andrew Kozak

This can be accomplished in a single line by leveraging similar functionality in PHP's built-in date/time functions. I humbly submit:

这可以通过利用 PHP 内置日期/时间函数中的类似功能在一行中完成。我谦虚地提出:

Solution:

解决方案:

function ordinalSuffix( $n )
{
  return date('S',mktime(1,1,1,1,( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
}

Detailed Explanation:

详细说明:

The built-in date()function has suffix logic for handling nth-day-of-the-month calculations. The suffix is returned when Sis given in the format string:

内置date()函数具有用于处理每月第 n 天计算的后缀逻辑。后缀S在格式字符串中给出时返回:

date( 'S' , ? );

Since date()requires a timestamp (for ?above), we'll pass our integer $nas the dayparameter to mktime()and use dummy values of 1for the hour, minute, second, and month:

由于date()需要的时间戳(对于?以上),我们将通过我们的整数$n作为day参数mktime()和使用假人值1hourminutesecond,和month

date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );

This actually fails gracefully on values out of range for a day of the month (i.e. $n > 31) but we can add some simple inline logic to cap $nat 29:

这实际上在一个月中的某一天(即$n > 31)超出范围的值时正常失败,但我们可以添加一些简单的内联逻辑以将上限设为$n29:

date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20))*10 + $n%10) ));

The only positive value(May 2017) this fails on is $n == 0, but that's easily fixed by adding 10 in that special case:

唯一的正值2017 年 5 月)这在 is 上失败$n == 0,但在这种特殊情况下通过添加 10 很容易解决:

date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));

Update, May 2017

更新,2017 年 5 月

As observed by @donatJ, the above fails above 100 (e.g. "111st"), since the >=20checks are always returning true. To reset these every century, we add a filter to the comparison:

正如@donatJ 所观察到的,上面的失败超过 100(例如“111st”),因为>=20检查总是返回 true。为了每个世纪重置这些,我们在比较中添加了一个过滤器:

date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n%100>=20)+($n==0))*10 + $n%10) ));

Just wrap it in a function for convenience and off you go!

为方便起见,只需将其包装在一个函数中即可!

回答by Paul

Here is a one-liner:

这是一个单行:

$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);

Probably the shortest solution. Can of course be wrapped by a function:

可能是最短的解决方案。当然可以用函数包装:

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);
}

Regards, Paul

问候, 保罗

EDIT1: Correction of code for 11 through 13.

EDIT1:更正 11 到 13 的代码。

EDIT2: Correction of code for 111, 211, ...

EDIT2:更正 111、211、...的代码

EDIT3: Now it works correctly also for multiples of 10.

EDIT3:现在它也适用于 10 的倍数。

回答by John Boker

from http://www.phpro.org/examples/Ordinal-Suffix.html

来自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;
}
?> 

回答by WhiteHorse

Simple and Easy Answer will be:

简单易行的答案将是:

$Day = 3; 
echo date("S", mktime(0, 0, 0, 0, $Day, 0));

//OUTPUT - rd

回答by iletras

I wrote this for PHP4. It's been working ok & it's pretty economical.

我为 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';  
}

回答by Chintan Thummar

you just need to apply given function.

你只需要应用给定的功能。

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';
}

回答by Uzair Bin Nisar

Generically, you can use that and call echo get_placing_string(100);

通常,您可以使用它并调用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';
}
?>

回答by nxasdf

I made a function that does not rely on the PHP's date();function as it's not necessary, but also made it as compact and as short as I think is currently possible.

我创建了一个不依赖 PHPdate();函数的函数,因为它不是必需的,但也使它尽可能紧凑和简短。

The code: (121 bytes total)

代码:(共 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')));
}

More compact code below.

下面更紧凑的代码。

It works as follows:

它的工作原理如下

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.

Stuff to know about this function:

有关此功能的信息

  • It deals with negative integers the same as positive integers and keeps the sign.
  • It returns 11th, 12th, 13th, 811th, 812th, 813th, etc. for the -teennumbers as expected.
  • It does not check decimals, but will leave them in place (use floor($i), round($i), or ceil($i)at the beginning of the final return statement).
  • You could also add format_number($i)at the beginning of the final return statement to get a comma-separated integer (if you're displaying thousands, millions, etc.).
  • You could just remove the $ifrom the beginning of the return statement if you only want to return the ordinal suffix without what you input.
  • 它与正整数一样处理负整数并保持符号。
  • 它按预期为-teen数字返回第 11、第 12、第 13、第 811、第 812、第 813 等。
  • 它不检查小数,但会将它们留在原处(使用floor($i), round($i), 或ceil($i)在最终 return 语句的开头)。
  • 您还可以format_number($i)在最终 return 语句的开头添加以获取逗号分隔的整数(如果您要显示千、百万等)。
  • $i如果您只想在没有输入内容的情况下返回序数后缀,则可以从 return 语句的开头删除。

This function works commencing PHP 5.2 released November 2006 purely because of the short array syntax. If you have a version before this, then please upgrade because you're nearly a decade out of date! Failing that, just replace the in-line ['st', 'nd', 'rd']with a temporary variable containing array('st', 'nd', 'rd');.

这个函数从 2006 年 11 月发布的 PHP 5.2 开始工作,纯粹是因为短数组语法。如果您有此之前的版本,那么请升级,因为您已经过时了近十年!如果失败,只需将内联替换为['st', 'nd', 'rd']包含array('st', 'nd', 'rd');.

The same function (without returning the input), but an exploded view of my short function for better understanding:

相同的函数(不返回输入),但我的简短函数的分解图以便更好地理解:

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
}

Code Update:

代码更新

Here's a modified version that is 14 whole bytes shorter (107 bytes total):

这是一个修改后的版本,缩短了 14 个字节(总共 107 个字节):

function ordinal($i) {
  return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');
}

Or for as short as possible being 25 bytes shorter (96 bytes total):

或者尽可能短 25 个字节(总共 96 个字节):

function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}

With this last function, simply call o(121);and it'll do exactly the same as the other functions I listed.

使用最后一个函数,只需调用o(121);它,它将与我列出的其他函数完全相同。

Code Update #2:

代码更新#2

Benand I worked together and cut it down by 38 bytes (83 bytes total):

Ben和我一起工作并将其减少了 38 个字节(总共 83 个字节):

function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}

We don't think it can possibly get any shorter than this! Willing to be proven wrong, however. :)

我们认为它不可能比这更短!然而,愿意被证明是错误的。:)

Hope you all enjoy.

希望大家喜欢。