ฉันต้องการแสดงตัวเลขดังนี้
- 1 เป็นที่ 1
- 2 เป็นที่ 2
- ... ,
- 150 เป็น 150
ฉันจะค้นหาคำต่อท้ายลำดับที่ถูกต้อง (st, nd, rd หรือ th) สำหรับแต่ละหมายเลขในรหัสของฉันได้อย่างไร
ฉันต้องการแสดงตัวเลขดังนี้
ฉันจะค้นหาคำต่อท้ายลำดับที่ถูกต้อง (st, nd, rd หรือ th) สำหรับแต่ละหมายเลขในรหัสของฉันได้อย่างไร
คำตอบ:
$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);
$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
PHP มีในตัวฟังก์ชั่นสำหรับการนี้ มันยังรองรับความเป็นสากล!
$locale = 'en_US';
$nf = new NumberFormatter($locale, NumberFormatter::ORDINAL);
echo $nf->format($number);
โปรดทราบว่าฟังก์ชั่นนี้มีเฉพาะใน PHP 5.3.0 และใหม่กว่า
NumberFomatter file not found
เสมอ คุณทำงานนี้ได้อย่างไร
apt-get install php5-intl
สามารถทำได้ในบรรทัดเดียวโดยใช้ประโยชน์จากฟังก์ชั่นที่คล้ายกันในฟังก์ชั่นวันที่ / เวลาของ PHP ฉันอ่อนน้อมถ่อมตน:
สารละลาย:
function ordinalSuffix( $n )
{
return date('S',mktime(1,1,1,1,( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
}
คำอธิบายโดยละเอียด:
date()
ฟังก์ชันในตัวมีตรรกะต่อท้ายสำหรับการจัดการการคำนวณ nth-day-of-the-month ส่วนต่อท้ายจะถูกส่งคืนเมื่อS
กำหนดในสตริงรูปแบบ:
date( 'S' , ? );
เนื่องจากdate()
ต้องมีการประทับเวลา (สำหรับการ?
ดังกล่าวข้างต้น) เราจะผ่านจำนวนเต็มของเรา$n
เป็นday
พารามิเตอร์mktime()
และการใช้หุ่นค่า1
สำหรับhour
, minute
, second
และmonth
:
date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );
สิ่งนี้ล้มเหลวได้อย่างงดงามในค่านอกช่วงสำหรับวันของเดือน (เช่น$n > 31
) แต่เราสามารถเพิ่มตรรกะอินไลน์แบบง่าย ๆ เพื่อเพิ่ม$n
ที่ 29:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20))*10 + $n%10) ));
ค่าบวกเท่านั้น( พฤษภาคม 2017 ) สิ่งนี้ล้มเหลวคือ$n == 0
แต่แก้ไขได้ง่ายโดยการเพิ่ม 10 ในกรณีพิเศษ:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
อัปเดต, พฤษภาคม 2560
ตามที่สังเกตโดย @donatJ ข้อผิดพลาดข้างต้นล้มเหลวเกิน 100 (เช่น "111st") เนื่องจากการ>=20
ตรวจสอบกลับคืนเป็นจริงเสมอ หากต้องการรีเซ็ตทุก ๆ ศตวรรษเราจะเพิ่มตัวกรองในการเปรียบเทียบ:
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);
}
ขอแสดงความนับถือ Paul
EDIT1: การแก้ไขรหัสสำหรับ 11 ถึง 13
EDIT2: การแก้ไขโค้ดสำหรับ 111, 211, ...
แก้ไข 3: ตอนนี้มันทำงานได้อย่างถูกต้องเช่นกันสำหรับทวีคูณของ 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';
}
คุณเพียงแค่ต้องใช้ฟังก์ชั่นที่กำหนด
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';
}
โดยทั่วไปคุณสามารถใช้และเรียก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();
ฟังก์ชั่นของ PHP เพราะมันไม่จำเป็น แต่ยังทำให้มันมีขนาดกะทัดรัดและสั้นที่สุดเท่าที่ฉันคิดว่าเป็นไปได้ในปัจจุบัน
รหัส : (รวม 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')));
}
รหัสกระชับมากขึ้นด้านล่าง
มันทำงานได้ดังต่อไปนี้ :
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.
สิ่งที่ควรรู้เกี่ยวกับฟังก์ชั่นนี้ :
floor($i)
, round($i)
หรือceil($i)
ที่จุดเริ่มต้นของคำสั่งคืนสุดท้าย)format_number($i)
ที่ต้นคำสั่งส่งคืนสุดท้ายเพื่อรับจำนวนเต็มคั่นด้วยเครื่องหมายจุลภาค (ถ้าคุณแสดงหลายพันล้าน ฯลฯ )$i
จากจุดเริ่มต้นของคำสั่งส่งคืนถ้าคุณเพียงต้องการที่จะกลับคำต่อท้ายลำดับที่ไม่มีสิ่งที่คุณป้อนฟังก์ชั่นนี้ใช้งานได้เริ่มตั้งแต่ PHP 5.2 ที่เผยแพร่ในเดือนพฤศจิกายน 2549 หมดจดเพราะมีไวยากรณ์ของอาร์เรย์แบบสั้น หากคุณมีรุ่นก่อนหน้านี้โปรดอัปเกรดเพราะคุณเกือบจะล้าสมัย! ความล้มเหลวที่เพียงแทนที่ในบรรทัดกับตัวแปรชั่วคราวที่มี['st', 'nd', 'rd']
array('st', 'nd', 'rd');
ฟังก์ชั่นเดียวกัน (โดยไม่ส่งคืนอินพุต) แต่เป็นมุมมองที่ขยายออกของฟังก์ชันสั้น ๆ ของฉันเพื่อความเข้าใจที่ดีขึ้น:
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
}
การปรับปรุงรหัส :
นี่คือเวอร์ชันที่แก้ไขซึ่งสั้นกว่า 14 ไบต์ (รวม 107 ไบต์):
function ordinal($i) {
return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');
}
หรือสั้นที่สุดเท่าที่จะเป็นไปได้คือ 25 ไบต์สั้นลง (รวม 96 ไบต์):
function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
ด้วยฟังก์ชั่นสุดท้ายนี้เพียงแค่เรียกo(121);
และมันก็จะเหมือนกับฟังก์ชั่นอื่น ๆ
การปรับปรุงรหัส # 2 :
เบ็นและฉันทำงานร่วมกันและตัดมันลง 38 ไบต์ (รวม 83 ไบต์):
function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
เราไม่คิดว่ามันจะสั้นไปกว่านี้! อย่างไรก็ตามเต็มใจที่จะพิสูจน์ว่าผิด :)
หวังว่าทุกคนจะสนุก
abs()
กับโมดูลัส%
abs();
ลบเครื่องหมายลบซึ่งเป็นสิ่งที่ฉันต้องการ
รุ่นที่สั้นลงสำหรับวันที่ในเดือน (สูงสุด 31) แทนที่จะใช้ mktime () และไม่ต้องการ pecl intl:
function ordinal($n) {
return (new DateTime('Jan '.$n))->format('jS');
}
หรือขั้นตอน:
echo date_format(date_create('Jan '.$n), 'jS');
ใช้งานได้แน่นอนเพราะเดือนที่เริ่มต้นที่ฉันเลือก (มกราคม) มี 31 วัน
น่าสนใจพอถ้าคุณลองกับเดือนกุมภาพันธ์ (หรืออีกเดือนที่ไม่มี 31 วัน) มันจะรีสตาร์ทก่อนสิ้น:
...clip...
31st
1st
2nd
3rd
ดังนั้นคุณสามารถนับได้ถึงวันของเดือนนี้ด้วยตัวระบุวันที่t
ในลูปของคุณ: จำนวนวันในเดือน
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;
}
พบคำตอบใน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';
}
?>
นี่คืออีกเวอร์ชั่นสั้นมากโดยใช้ฟังก์ชั่นวันที่ มันทำงานได้กับตัวเลขใด ๆ (ไม่ จำกัด ตามวันของเดือน) และคำนึงถึงว่า * 11 * 12th * 13th ไม่เป็นไปตามรูปแบบ * 1 * 2 * 3
function getOrdinal($n)
{
return $n . date_format(date_create('Jan ' . ($n % 100 < 20 ? $n % 20 : $n % 10)), 'S');
}
ฉันชอบตัวอย่างเล็ก ๆ นี้
<?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';
}
?>