development

PHP에서 서 수가 붙은 숫자 표시

big-blog 2020. 6. 25. 07:30
반응형

PHP에서 서 수가 붙은 숫자 표시


다음과 같이 숫자를 표시하고 싶습니다

  • 1을 1로,
  • 2를 2로,
  • ...,
  • 150은 150입니다.

코드에서 각 숫자의 올바른 서수 (st, nd, rd 또는 th)를 어떻게 찾습니까?


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

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

PHP에는이 기능이 내장되어 있습니다 . 국제화도 처리합니다!

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

이 기능은 PHP 5.3.0 이상에서만 사용할 수 있습니다.


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는 AS day에 대한 매개 변수 mktime()의 값 더미 및 사용 1에 대한 hour, minute, second, 및 month:

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

이것은 실제로 한 달 동안 범위를 벗어난 값에서 정상적으로 실패 $n > 31하지만 ( $n29) 간단한 인라인 논리를 추가 하여 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검사가 항상 참을 반환하기 때문에 위의 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;
}
?> 

간단하고 쉬운 답변은 다음과 같습니다.

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

//OUTPUT - rd

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

당신은 주어진 기능을 적용해야합니다.

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

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.

The code: (121 bytes total)

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 -teen numbers 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 $i from the beginning of the return statement if you only want to return the ordinal suffix without what you input.

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

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

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

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.

Code Update #2:

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

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.


An even shorter version for dates in the month (up to 31) instead of using mktime() and not requiring pecl intl:

function ordinal($n) {
    return (new DateTime('Jan '.$n))->format('jS');
}

or procedurally:

echo date_format(date_create('Jan '.$n), 'jS');

This works of course because the default month I picked (January) has 31 days.

Interestingly enough if you try it with February (or another month without 31 days), it restarts before the end:

...clip...
31st
1st
2nd
3rd

so you could count up to this month's days with the date specifier t in your loop: number of days in the month.


function ordinal($number){

    $last=substr($number,-1);
    if( $last>3 || $last==0 || ( $number >= 11 && $number <= 19 ) ){
      $ext='th';
    }else if( $last==3 ){
      $ext='rd';
    }else if( $last==2 ){
      $ext='nd';
    }else{
      $ext='st';
    }
    return $number.$ext;
  }

Found an answer in 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';
}
?>

Here's another very short version using the date functions. It works for any number (not constrained by days of the month) and takes into account that *11th *12th *13th does not follow the *1st *2nd *3rd format.

function getOrdinal($n)
{
    return $n . date_format(date_create('Jan ' . ($n % 100 < 20 ? $n % 20 : $n % 10)), 'S');
}

I fond this small snippet

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

?>

HERE

참고URL : https://stackoverflow.com/questions/3109978/display-numbers-with-ordinal-suffix-in-php

반응형