Tôi muốn hiển thị số như sau
- 1 là 1,
- 2 là 2,
- ...,
- 150 như 150.
Làm thế nào tôi nên tìm đúng hậu tố thứ tự (st, nd, nd hoặc th) cho mỗi số trong mã của tôi?
Tôi muốn hiển thị số như sau
Làm thế nào tôi nên tìm đúng hậu tố thứ tự (st, nd, nd hoặc th) cho mỗi số trong mã của tôi?
Câu trả lời:
$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];
Trong trường hợp $number
là số bạn muốn viết. Hoạt động với bất kỳ số tự nhiên.
Là một chức năng:
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 có chức năng tích hợp sẵn cho việc này . Nó thậm chí còn xử lý quốc tế hóa!
$locale = 'en_US';
$nf = new NumberFormatter($locale, NumberFormatter::ORDINAL);
echo $nf->format($number);
Lưu ý rằng chức năng này chỉ có sẵn trong PHP 5.3.0 trở lên.
NumberFomatter file not found
. Làm thế nào bạn làm việc xung quanh này?
apt-get install php5-intl
Điều này có thể được thực hiện trong một dòng bằng cách tận dụng chức năng tương tự trong các hàm ngày / giờ tích hợp của PHP. Tôi khiêm tốn nộp:
Giải pháp:
function ordinalSuffix( $n )
{
return date('S',mktime(1,1,1,1,( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
}
Giải thích chi tiết:
Hàm tích hợp date()
có logic hậu tố để xử lý các phép tính ngày thứ n của tháng. Hậu tố được trả về khi S
được đưa ra trong chuỗi định dạng:
date( 'S' , ? );
Kể từ khi date()
đòi hỏi một dấu thời gian (đối với ?
trên), chúng tôi sẽ vượt qua số nguyên của chúng tôi $n
là day
tham số để mktime()
và sử dụng hình nộm giá trị của 1
cho hour
, minute
, second
, và month
:
date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );
Điều này thực sự thất bại một cách duyên dáng trên các giá trị ngoài phạm vi cho một ngày trong tháng (nghĩa là $n > 31
) nhưng chúng ta có thể thêm một số logic nội tuyến đơn giản vào giới hạn $n
ở 29:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20))*10 + $n%10) ));
Giá trị dương duy nhất( Tháng 5 năm 2017 ) điều này không thành công $n == 0
, nhưng điều đó dễ dàng được khắc phục bằng cách thêm 10 trong trường hợp đặc biệt đó:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
Cập nhật, tháng 5 năm 2017
Theo quan sát của @donatJ, các lỗi trên 100 (ví dụ "111st"), vì các >=20
kiểm tra luôn luôn trả về đúng. Để thiết lập lại những thế kỷ này, chúng tôi thêm một bộ lọc để so sánh:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n%100>=20)+($n==0))*10 + $n%10) ));
Chỉ cần bọc nó trong một chức năng cho thuận tiện và tắt bạn đi!
Đây là một lót:
$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);
Có lẽ là giải pháp ngắn nhất. Tất nhiên có thể được bọc bởi một chức năng:
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);
}
Trân trọng, Paul
EDIT1: Sửa mã cho 11 đến 13.
EDIT2: Sửa mã cho 111, 211, ...
EDIT3: Bây giờ nó hoạt động chính xác cũng cho bội số của 10.
từ 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;
}
?>
Tôi đã viết cái này cho PHP4. Nó hoạt động tốt và nó khá kinh tế.
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';
}
bạn chỉ cần áp dụng chức năng nhất định.
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';
}
Nói chung, bạn có thể sử dụng điều đó và gọi echo get_places_opes (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';
}
?>
Tôi đã tạo ra một hàm không dựa vào date();
hàm của PHP vì nó không cần thiết, nhưng cũng làm cho nó nhỏ gọn và ngắn như tôi nghĩ hiện có thể.
Mã : (tổng cộng 121 byte)
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')));
}
Mã nhỏ gọn hơn dưới đây.
Nó hoạt động như sau :
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.
Những điều cần biết về chức năng này :
floor($i)
, round($i)
hoặc ceil($i)
ở phần đầu của câu lệnh return cuối cùng).format_number($i)
vào đầu câu lệnh hoàn trả cuối cùng để lấy số nguyên được phân tách bằng dấu phẩy (nếu bạn đang hiển thị hàng nghìn, hàng triệu, v.v.).$i
từ đầu câu lệnh return nếu bạn chỉ muốn trả về hậu tố thứ tự mà không cần nhập gì.Hàm này hoạt động bắt đầu PHP 5.2 được phát hành vào tháng 11 năm 2006 hoàn toàn do cú pháp mảng ngắn. Nếu bạn có phiên bản trước đó, thì vui lòng nâng cấp vì bạn đã gần một thập kỷ lỗi thời! Không, chỉ cần thay thế nội tuyến ['st', 'nd', 'rd']
bằng một biến tạm thời có chứa array('st', 'nd', 'rd');
.
Hàm tương tự (không trả về đầu vào), nhưng chế độ xem bùng nổ của hàm ngắn của tôi để hiểu rõ hơn:
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
}
Cập nhật mã :
Đây là phiên bản sửa đổi ngắn hơn 14 byte (tổng 107 byte):
function ordinal($i) {
return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');
}
Hoặc càng ngắn càng tốt, ngắn hơn 25 byte (tổng cộng 96 byte):
function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
Với chức năng cuối cùng này, chỉ cần gọi o(121);
và nó sẽ thực hiện chính xác như các chức năng khác mà tôi đã liệt kê.
Cập nhật mã số 2 :
Ben và tôi đã làm việc cùng nhau và cắt giảm 38 byte (tổng cộng 83 byte):
function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
Chúng tôi không nghĩ rằng nó có thể có thể ngắn hơn thế này! Sẵn sàng để được chứng minh là sai, tuy nhiên. :)
Hy vọng tất cả các bạn thích.
abs()
với mô-đun%
abs();
loại bỏ các dấu hiệu tiêu cực đó là những gì tôi cần.
Một phiên bản thậm chí ngắn hơn cho các ngày trong tháng (tối đa 31) thay vì sử dụng mktime () và không yêu cầu pecl intl:
function ordinal($n) {
return (new DateTime('Jan '.$n))->format('jS');
}
hoặc thủ tục:
echo date_format(date_create('Jan '.$n), 'jS');
Điều này tất nhiên hoạt động vì tháng mặc định tôi chọn (tháng 1) có 31 ngày.
Thật thú vị nếu bạn thử nó với tháng hai (hoặc một tháng khác mà không có 31 ngày), nó sẽ khởi động lại trước khi kết thúc:
...clip...
31st
1st
2nd
3rd
do đó bạn có thể đếm đến ngày của tháng này với công cụ xác định ngày t
trong vòng lặp của bạn: số ngày trong tháng.
Tìm thấy câu trả lời trong 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';
}
?>
Đây là một phiên bản rất ngắn khác sử dụng các chức năng ngày. Nó hoạt động cho bất kỳ số nào (không bị hạn chế bởi các ngày trong tháng) và tính đến việc * 11th * 12th * 13 không tuân theo định dạng * 1 * 2 * 3.
function getOrdinal($n)
{
return $n . date_format(date_create('Jan ' . ($n % 100 < 20 ? $n % 20 : $n % 10)), 'S');
}
Tôi thích đoạn nhỏ này
<?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';
}
?>