Numaraları aşağıdaki gibi görüntülemek istiyorum
- 1'inci,
- 2, 2,
- ...,
- 150, 150.
Kodumdaki her numara için doğru sıra son ekini (st, nd, rd veya th) nasıl bulmalıyım?
Numaraları aşağıdaki gibi görüntülemek istiyorum
Kodumdaki her numara için doğru sıra son ekini (st, nd, rd veya th) nasıl bulmalıyım?
Yanıtlar:
$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];
$numberYazmak istediğin numara nerede . Herhangi bir doğal sayı ile çalışır.
İşlev olarak:
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, bunun için yerleşik işlevselliğe sahiptir . Uluslararasılaşmayı bile idare ediyor!
$locale = 'en_US';
$nf = new NumberFormatter($locale, NumberFormatter::ORDINAL);
echo $nf->format($number);
Bu işlevselliğin yalnızca PHP 5.3.0 ve sonrasında kullanılabildiğini unutmayın.
NumberFomatter file not found. Bu konuda nasıl çalıştınız?
apt-get install php5-intl
Bu, PHP'nin yerleşik tarih / saat işlevlerindeki benzer işlevlerden yararlanılarak tek bir satırda gerçekleştirilebilir. Alçakgönüllülükle sunuyorum:
Çözüm:
function ordinalSuffix( $n )
{
return date('S',mktime(1,1,1,1,( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
}
Detaylı açıklama:
Yerleşik date()fonksiyonu inci günlük-of-the-aylık hesaplamaları işlemek için sonek mantığı vardır. Sonek, Sbiçim dizesinde verildiğinde döndürülür :
date( 'S' , ? );
Yana date()bir zaman damgası (için gerektirir ?yukarıda), bizim tamsayı geçmek olacak $nşekilde dayparametre mktime()değerleri kukla ve kullanım 1için hour, minute, second, ve month:
date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );
Bu aslında ayın bir günü için aralık dışı değerlerde zarif bir şekilde başarısız olur (yani $n > 31), ancak $n29'da sınırlamak için bazı basit satır içi mantık ekleyebiliriz :
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20))*10 + $n%10) ));
Tek pozitif değer( Mayıs 2017 ) bu başarısız olur $n == 0, ancak bu özel durumda 10 ekleyerek kolayca düzeltilebilir:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
Güncelleme, Mayıs 2017
@DonatJ tarafından gözlemlendiği gibi, >=20kontroller her zaman doğruya döndüğünden, yukarıdaki 100'ün üzerinde başarısız olur (ör. "111.") . Bunları her yüzyılda sıfırlamak için, karşılaştırmaya bir filtre ekliyoruz:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n%100>=20)+($n==0))*10 + $n%10) ));
Kolaylık sağlamak için onu bir fonksiyona sarın ve başlayın!
İşte tek satırlık:
$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);
Muhtemelen en kısa çözüm. Elbette bir işlevle sarılabilir:
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);
}
Saygılarımızla, Paul
DÜZENLEME1: 11'den 13'e kadar kodun düzeltilmesi.
EDIT2: 111, 211, ... için kod düzeltmesi
DÜZENLEME3: Artık 10'un katları için de doğru çalışıyor.
dan 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;
}
?>
Bunu PHP4 için yazdım. İyi çalışıyor ve oldukça ekonomik.
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';
}
sadece verilen işlevi uygulamanız gerekir.
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';
}
Genel olarak, bunu kullanabilir ve 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';
}
?>
date();Gerekli olmadığı için PHP'nin işlevine güvenmeyen , aynı zamanda onu şu anda mümkün olduğunu düşündüğüm kadar kompakt ve kısa yapan bir işlev yaptım.
Kod : (toplam 121 bayt)
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')));
}
Aşağıda daha kompakt kod.
Aşağıdaki gibi çalışır :
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.
Bu işlev hakkında bilinmesi gerekenler :
floor($i), round($i)ya da ceil($i)son iade ifade başında).format_number($i)Virgülle ayrılmış bir tam sayı elde etmek için son dönüş ifadesinin başına da ekleyebilirsiniz (binleri, milyonları vb. Görüntülüyorsanız).$iYalnızca sıra soneki girdiğiniz şey olmadan döndürmek istiyorsanız, return ifadesinin başından kaldırabilirsiniz .Bu işlev, yalnızca kısa dizi sözdizimi nedeniyle Kasım 2006'da yayınlanan PHP 5.2'den başlayarak çalışır. Bundan önce bir sürümünüz varsa, lütfen güncellemeyi neredeyse on yıl geçirdiğiniz için yükseltin! Başarısız olursa, satır içi ['st', 'nd', 'rd']olanı içeren geçici bir değişkenle değiştirin array('st', 'nd', 'rd');.
Aynı işlev (girdiyi döndürmeden), ancak daha iyi anlamak için kısa işlevimin parçalara ayrılmış bir görünümü:
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
}
Kod Güncellemesi :
İşte 14 tam bayt daha kısa (toplam 107 bayt) değiştirilmiş bir sürüm:
function ordinal($i) {
return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');
}
Veya 25 bayt daha kısa (toplam 96 bayt) olabildiğince kısa:
function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
Bu son işlevle, basitçe arayın o(121);ve listelediğim diğer işlevlerle tam olarak aynı şeyi yapacaktır.
Kod Güncellemesi # 2 :
Ben ve ben birlikte çalıştık ve 38 bayt (toplam 83 bayt) azalttık:
function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
Bundan daha kısalabileceğini düşünmüyoruz! Ancak yanlış olduğu kanıtlanmaya istekli. :)
Umarım hepiniz eğlenirsiniz.
abs()modül ile kullanmanıza gerek yok%
abs();ihtiyacım olan negatif işareti kaldırır.
Mktime () kullanmak yerine ve pecl intl gerektirmeyen ay içindeki tarihler için (31'e kadar) daha da kısa bir versiyon:
function ordinal($n) {
return (new DateTime('Jan '.$n))->format('jS');
}
veya prosedürel olarak:
echo date_format(date_create('Jan '.$n), 'jS');
Elbette bu işe yarıyor çünkü seçtiğim varsayılan ayın (Ocak) 31 günü var.
İlginçtir ki, Şubat ayında (veya 31 gün olmadan başka bir ay) denerseniz, sonundan önce yeniden başlar:
...clip...
31st
1st
2nd
3rd
Böylece, döngünüzdeki tarih belirleyicisiyle bu ayın günlerini sayabilirsiniz t: aydaki gün sayısı.
PHP.net'te bir cevap bulundu
<?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';
}
?>
İşte tarih işlevlerini kullanan çok kısa bir versiyon. Herhangi bir sayı için çalışır (ayın günleri ile sınırlandırılmamıştır) ve * 11. * 12. * 13. * 1. * 2. * 3. formatı takip etmediğini dikkate alır.
function getOrdinal($n)
{
return $n . date_format(date_create('Jan ' . ($n % 100 < 20 ? $n % 20 : $n % 10)), 'S');
}
Bu küçük parçacığı seviyorum
<?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';
}
?>