it-swarm.com.de

Zeigt Zahlen mit Ordnungssuffix an PHP

Ich möchte Zahlen wie folgt anzeigen

  • 1 als 1.,
  • 2 als 2.,
  • ...
  • 150 als 150.

Wie finde ich für jede Zahl in meinem Code das richtige Suffix für Ordinalzahlen (st, nd, rd oder th)?

124
ArK

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

Dabei ist $number die Nummer, die Sie schreiben möchten. Funktioniert mit einer beliebigen natürlichen Nummer.

Als eine Funktion:

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

PHP hat dafür eine integrierte Funktionalität . Es kümmert sich sogar um Internationalisierung!

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

Beachten Sie, dass diese Funktionalität nur in PHP 5.3.0 und höher verfügbar ist.

113
Jeremy Kauffman

Dies kann in einer einzigen Zeile erfolgen, indem ähnliche Funktionen in den integrierten Datums-/Uhrzeitfunktionen von PHP verwendet werden. Demütig gebe ich:

Lösung:

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

Ausführliche Erklärung:

Die eingebaute date() - Funktion verfügt über eine Suffix-Logik zur Verarbeitung von Berechnungen für den n-ten Tag des Monats. Das Suffix wird zurückgegeben, wenn in der Formatzeichenfolge S angegeben ist:

date( 'S' , ? );

Da date() einen Zeitstempel erfordert (für ? oben), übergeben wir unseren Integer $n als Parameter day an mktime() und verwenden Dummy-Werte von 1 für hour, minute, second und month:

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

Dies scheitert an Werten außerhalb des gültigen Bereichs für einen Tag des Monats (d. H. $n > 31), aber wir können einige einfache Inline-Logik hinzufügen, um $n bei 29 zu begrenzen:

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

Der einzig positive Wert(Mai 2017) dies schlägt fehl bei $n == 0, aber das lässt sich leicht durch Hinzufügen von 10 in diesem speziellen Fall beheben:

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

Update, Mai 2017

Wie von @donatJ festgestellt, fällt das obige über 100 (z. B. "111st") aus, da die >=20-Prüfungen immer wahr zurückgeben. Um diese jedes Jahrhundert zurückzusetzen, fügen wir dem Vergleich einen Filter hinzu:

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

Einfach in eine Funktion einpacken und los geht's!

16
Andrew Kozak

Hier ist ein Einzeiler:

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

Wahrscheinlich die kürzeste Lösung. Kann natürlich von einer Funktion umschlossen werden:

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

Viele Grüße. Paul

EDIT1: Korrektur des Codes für 11 bis 13.

EDIT2: Korrektur des Codes für 111, 211, ...

EDIT3: Jetzt funktioniert es auch für Vielfache von 10.

14
Paul

aus 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;
}
?> 
13
John Boker

Ich habe dies für PHP4 geschrieben ... Es hat gut funktioniert und es ist ziemlich sparsam.

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

Einfache und einfache Antwort wird sein:

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

//OUTPUT - rd
6
WhiteHorse

sie müssen nur die angegebene Funktion anwenden.

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

Generisch können Sie das verwenden und echo get_placing_string (100) aufrufen.

<?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';
}
?>
3
Uzair Bin Nisar

Ich habe eine Funktion erstellt, die nicht auf die date();-Funktion von PHP angewiesen ist, da sie nicht notwendig ist, sondern sie auch so kompakt und so kurz wie ich denke, ist derzeit möglich.

Der Code: (insgesamt 121 Bytes)

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

Mehr kompakter Code unten.

Es funktioniert wie folgt:

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.

Wissenswertes über diese Funktion:

  • Es behandelt negative ganze Zahlen genauso wie positive ganze Zahlen und behält das Zeichen.
  • Es liefert 11., 12., 13., 811., 812., 813. usw. für die -teen-Zahlen wie erwartet zurück.
  • Es werden keine Dezimalstellen geprüft, aber sie werden an Ort und Stelle belassen (verwenden Sie floor($i), round($i) oder ceil($i) am Anfang der abschließenden Return-Anweisung).
  • Sie können auch format_number($i) am Anfang der letzten return-Anweisung hinzufügen, um eine durch Kommas getrennte Ganzzahl zu erhalten (wenn Sie Tausende, Millionen usw. anzeigen).
  • Sie können den $i einfach vom Anfang der return-Anweisung entfernen, wenn Sie nur das Ordinal-Suffix ohne Ihre Eingaben zurückgeben möchten.

Diese Funktion funktioniert ab PHP 5.2 nur aufgrund der Short-Array-Syntax. Wenn Sie zuvor eine Version haben, dann aktualisieren Sie bitte, da Sie fast ein Jahrzehnt veraltet sind! Andernfalls ersetzen Sie einfach den Inline-Code ['st', 'nd', 'rd'] durch eine temporäre Variable, die array('st', 'nd', 'rd'); enthält.

Dieselbe Funktion (ohne Eingabe der Eingabe), jedoch eine Explosionsansicht meiner kurzen Funktion zum besseren Verständnis:

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:

Hier ist eine modifizierte Version, die 14 ganze Bytes kürzer ist (insgesamt 107 Bytes):

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

Oder so kurz wie möglich, 25 Bytes kürzer (96 Bytes insgesamt):

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

Mit dieser letzten Funktion rufen Sie einfach o(121); auf, und es wird genau das gleiche wie bei den anderen Funktionen ausgeführt, die ich aufgelistet habe.

Code Update # 2:

Ben und ich arbeiteten zusammen und reduzierten es um 38 Bytes (insgesamt 83 Bytes):

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

Wir glauben nicht, dass es kürzer sein kann als dies! Bereit, sich jedoch als falsch zu beweisen. :)

Ich hoffe, es gefällt euch allen.

2
nxasdf
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;
  }
1
xyz

Um die Antwort von Lacopo weiter zu vereinfachen, können Sie die folgende Funktion verwenden, die die letzte Ziffer der Zahl mithilfe der Funktion substr () abruft und sie als Index des $ ends-Arrays verwendet.

function get_ordinal($number)
{
    $ends=array('th','st','nd','rd','th','th','th','th','th','th');
    $last_digit=substr($number, -1, 1);
    return $number.$ends[$last_digit];
}

Bearbeiten

Meine obige Funktion scheint bei den mit 11, 12, 13 endenden Zahlen zu scheitern, was mir beim Schreiben der Antwort nicht aufgefallen ist. Verwenden Sie also die Antwort von Lacopo.

0
Bilal Shareef

Hier ist eine weitere sehr kurze Version mit Datumsfunktionen. Es funktioniert für eine beliebige Zahl (nicht an den Tagen des Monats gebunden) und berücksichtigt, dass * 11 * * 12 * 13. Nicht dem * 1 * 2 * * 3 Format folgt.

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

Antwort gefunden 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';
}
?>
0
mysticmo

Eine noch kürzere Version für Datumsangaben (bis zu 31) anstelle von mktime () und ohne pecl intl:

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

oder verfahrenstechnisch:

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

Dies funktioniert natürlich, weil der voreingestellte Monat (Januar) 31 Tage hat.

Interessanterweise, wenn Sie es mit Februar (oder einem anderen Monat ohne 31 Tage) versuchen, wird es vor dem Ende neu gestartet:

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

sie können also bis zu diesem Monat mit der Datumsangabe t in Ihrer Schleife zählen: Anzahl der Tage im Monat.

0
Dan Dart