Ich möchte Zahlen wie folgt anzeigen
- 1 als 1.,
- 2 als 2.,
- ...,
- 150 als 150 ..
Wie finde ich das richtige Ordnungssuffix (st, nd, rd oder th) für jede Zahl in meinem Code?
Ich möchte Zahlen wie folgt anzeigen
Wie finde ich das richtige Ordnungssuffix (st, nd, rd oder th) für jede Zahl in meinem Code?
Antworten:
$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];
Wo $number
ist die Nummer, die Sie schreiben möchten? Funktioniert mit jeder natürlichen Zahl.
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);
$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
PHP verfügt hierfür über integrierte Funktionen . Es kümmert sich sogar um die 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.
NumberFomatter file not found
. Wie haben Sie das umgangen?
apt-get install php5-intl
Dies kann in einer einzigen Zeile erreicht werden, indem ähnliche Funktionen in den in PHP integrierten Datums- / Uhrzeitfunktionen genutzt werden. Ich reiche demütig ein:
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 integrierte date()
Funktion verfügt über eine Suffix-Logik für die Berechnung des n-ten Tages des Monats. Das Suffix wird zurückgegeben, wenn S
es in der Formatzeichenfolge angegeben wird:
date( 'S' , ? );
Da date()
ein Zeitstempel (für erfordert ?
oben), werden wir unsere ganze Zahl übergeben $n
als day
Parameter mktime()
und die Verwendung Blindwerte 1
für die hour
, minute
, second
und month
:
date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );
Dies schlägt bei Werten außerhalb des Bereichs für einen Tag des Monats (dh $n > 31
) ordnungsgemäß fehl, aber wir können eine 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 $n == 0
, aber das lässt sich leicht beheben, indem in diesem speziellen Fall 10 hinzugefügt werden:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
Update, Mai 2017
Wie von @donatJ beobachtet, schlägt das Obige über 100 fehl (z. B. "111."), da die >=20
Überprüfungen immer true 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) ));
Wickeln Sie es einfach in eine Funktion ein und los geht's!
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);
}
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 richtig.
von 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;
}
?>
Einfache und einfache Antwort lautet:
$Day = 3;
echo date("S", mktime(0, 0, 0, 0, $Day, 0));
//OUTPUT - rd
Ich habe das für PHP4 geschrieben. Es hat gut funktioniert und 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';
}
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';
}
Generell 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';
}
?>
Ich habe eine Funktion erstellt, die sich nicht auf die PHP- date();
Funktion stützt, da sie nicht erforderlich ist, sondern sie auch so kompakt und kurz gemacht hat, wie ich derzeit für möglich halte.
Der Code : (121 Bytes insgesamt)
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')));
}
Kompakterer 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 zu dieser Funktion :
floor($i)
, round($i)
oder ceil($i)
am Anfang der letzten return - Anweisung).format_number($i)
am Anfang der endgültigen return-Anweisung hinzufügen , um eine durch Kommas getrennte Ganzzahl zu erhalten (wenn Sie Tausende, Millionen usw. anzeigen).$i
vom Anfang der return-Anweisung entfernen, wenn Sie nur das Ordnungssuffix ohne Ihre Eingabe zurückgeben möchten.Diese Funktion funktioniert ab PHP 5.2, das im November 2006 veröffentlicht wurde, allein aufgrund der kurzen Array-Syntax. Wenn Sie zuvor eine Version haben, aktualisieren Sie diese bitte, da Sie fast ein Jahrzehnt veraltet sind! Andernfalls ersetzen Sie einfach die Inline ['st', 'nd', 'rd']
durch eine temporäre Variable, die enthält array('st', 'nd', 'rd');
.
Dieselbe Funktion (ohne Rückgabe der Eingabe), aber eine Explosionsansicht meiner Kurzfunktion 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-Aktualisierung :
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 (insgesamt 96 Bytes):
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 o(121);
Sie einfach auf und es wird genau das gleiche tun wie die anderen Funktionen, die ich aufgelistet habe.
Code Update # 2 :
Ben und ich haben zusammengearbeitet und es um 38 Bytes (insgesamt 83 Bytes) reduziert:
function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
Wir glauben nicht, dass es kürzer werden kann! Bereit, sich jedoch als falsch zu erweisen. :) :)
Hoffe euch allen gefällt es.
abs()
mit Modul verwenden%
abs();
Entfernt das negative Vorzeichen, das ich brauchte.
Eine noch kürzere Version für Daten im Monat (bis zu 31) anstelle von mktime () und ohne pecl intl:
function ordinal($n) {
return (new DateTime('Jan '.$n))->format('jS');
}
oder prozedural:
echo date_format(date_create('Jan '.$n), 'jS');
Dies funktioniert natürlich, da der von mir ausgewählte Standardmonat (Januar) 31 Tage hat.
Interessanterweise wird es vor dem Ende neu gestartet, wenn Sie es mit Februar (oder einem anderen Monat ohne 31 Tage) versuchen:
...clip...
31st
1st
2nd
3rd
Mit dem Datumsangaben t
in Ihrer Schleife können Sie also bis zu den Tagen dieses Monats zählen : Anzahl der Tage im Monat.
In PHP.net eine Antwort gefunden
<?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';
}
?>
Hier ist eine weitere sehr kurze Version mit den Datumsfunktionen. Es funktioniert für jede Anzahl (nicht durch Tage des Monats beschränkt) und berücksichtigt, dass * 11th * 12th * 13th nicht dem * 1st * 2nd * 3rd-Format folgt.
function getOrdinal($n)
{
return $n . date_format(date_create('Jan ' . ($n % 100 < 20 ? $n % 20 : $n % 10)), 'S');
}
Ich mag diesen kleinen Ausschnitt
<?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';
}
?>