Mira mi respuesta aquí. stackoverflow.com/questions/69262/… Esa pregunta era para .NET, pero respondí con una solución PHP, por lo que debería ayudarte.
nickf
La única forma en que puedo pensar en hacer esto es tener una declaración if para cada número que pueda tener, es decir, if (1) luego "st" elseif (2) luego "nd", etc., etc. if (23000) luego " Dakota del Norte". Es un problema si tiene números grandes, pero podría escribir un programa para escribir el código por usted, podría repetir todos los números imprimiendo los ifs para que copie + pegue en su código.
Tom Gullen
2
@ Tom, una tabla de búsqueda podría ser mejor, simplemente inicialícela con los valores de 23000 y obtenga el valor en el índice n, donde n es el número que desea el ordinal.
John Boker
2
Col. Metralla. Puedes brillar pero no todos. de todos modos, gracias por mostrar interés en mi pregunta
ArK
@John, idea muy muy inteligente, sería muy rápido acceder y cada índice representa el número que está buscando.
Aunque un poco difícil de entender al principio, ahora creo que representa mejor cómo funciona el sistema de sufijos ordinales para el inglés.
erisco
66
Me gusta tu solución Además, si prefiere no generar 0, modifique la última línea para ser$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
Gavin Jackson
1
@GavinJackson, tu incorporación a esta excelente solución realmente me ayudó (+1). ¿Podría explicarme qué está pasando en el cálculo? Quiero entender. ¡Salud! EDITAR: Se encontró una respuesta: operador condicional
Andrew Fox
Lo sentimos, tuve que romper los 111 votos a 112: D Lo hizo una función en Delphi junto con una aplicación de demostración: pastebin.com/wvmz1CHY
Jerry Dodge
1
@HafezDivandari: ¿estás seguro? Acabo de probar con 7.1.19 y parece funcionar bien
Tenga en cuenta que esto también requiere PECL intl> = 1.0.0
rymo
44
¿Sabes si es posible obtener el número ordinal en forma de palabra? es decir, primero, segundo, tercero, etc. en lugar de primero, segundo, tercero ...
its_me
@jeremy Cuando traté de usar NumberFormatter, siempre arroja un error que NumberFomatter file not found. ¿Cómo resolviste esto?
jhnferraris
1
@Jhn tienes que instalar la extensiónapt-get install php5-intl
Aley
@Aley ya veo. Yii tiene un formateador incorporado que estamos usando en este momento. je
jhnferraris
20
Esto se puede lograr en una sola línea aprovechando una funcionalidad similar en las funciones de fecha / hora integradas de PHP. Humildemente presento:
Solución:
function ordinalSuffix( $n ){return date('S',mktime(1,1,1,1,((($n>=10)+($n>=20)+($n==0))*10+ $n%10)));}
Explicación detallada:
La date()función incorporada tiene lógica de sufijo para manejar los cálculos del enésimo día del mes. El sufijo se devuelve cuando Sse da en la cadena de formato:
date('S',?);
Dado que date()requiere una marca de tiempo (por ?arriba), vamos a pasar nuestro número entero $ncomo el dayparámetro a mktime()y el uso de los valores ficticia 1para el hour, minute, second, y month:
date('S', mktime(1,1,1,1, $n ));
Esto realmente falla con gracia en valores fuera de rango para un día del mes (es decir $n > 31), pero podemos agregar una lógica en línea simple para limitar $na 29:
Como observó @donatJ, lo anterior falla por encima de 100 (por ejemplo, "111"), ya que las >=20comprobaciones siempre devuelven verdadero. Para restablecer estos cada siglo, agregamos un filtro a la comparación:
Me gusta este enfoque, pero por desgracia, no funciona :-( 30 sale como 30. 40 sale como 40. etc.
Flukey
1
Si lo siento Cuando leí la pregunta que pensé, hey, esto debería ser posible con una sola línea de código. Y lo acabo de escribir. Como puede ver en mis ediciones, estoy mejorando. Después de la tercera edición ahora creo que está bastante hecho. Al menos todos los números del 1 al 150 se imprimen bien en mi pantalla.
Paul
Se ve bien hasta 500! (No lo he probado más que eso). ¡Buen trabajo! :-)
No dice nada sobre fechas en la pregunta aunque. Elevé mi voto de todos modos: es una solución rápida y simple cuando sabes que el rango de números será <32
cronoklee
8
Escribí esto para PHP4. Ha estado funcionando bien y es bastante económico.
Hice una función que no se basa en la date();función de PHP, ya que no es necesaria, pero también la hice tan compacta y tan corta como creo que es posible actualmente.
El código : (121 bytes en total)
function ordinal($i){// PHP 5.2 and laterreturn($i.(($j=abs($i)%100)>10&&$j<14?'th':(($j%=10)>0&&$j<4?['st','nd','rd'][$j-1]:'th')));}
Código más compacto a continuación.
Funciona de la siguiente manera :
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.
Cosas que debes saber sobre esta función :
Se trata de enteros negativos igual que los enteros positivos y mantiene el signo.
Devuelve 11, 12, 13, 811, 812, 813, etc. para los números de dieciséis como se esperaba.
No comprueba decimales, pero los dejará en su lugar (uso floor($i), round($i)o ceil($i)al comienzo de la instrucción de retorno final).
También puedes agregar format_number($i) al comienzo de la declaración de devolución final para obtener un número entero separado por comas (si está mostrando miles, millones, etc.).
Simplemente puede eliminar el $idel principio de la declaración de devolución si solo desea devolver el sufijo ordinal sin lo que ingresó.
Esta función funciona a partir de PHP 5.2, lanzado en noviembre de 2006, simplemente debido a la sintaxis de matriz corta. Si tiene una versión anterior a esta, ¡actualice ya que está casi una década desactualizada! De lo contrario, simplemente reemplace el en línea ['st', 'nd', 'rd']con una variable temporal que contengaarray('st', 'nd', 'rd'); .
La misma función (sin devolver la entrada), pero una vista explosionada de mi función corta para una mejor comprensión:
function ordinal($i){
$j = abs($i);// make negatives into positives
$j = $j%100;// modulo 100; deal only with ones and tens; 0 through 99if($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 9if($j==1)// 1st, 21st, 31st, 971streturn('st');if($j==2)// 2nd, 22nd, 32nd, 582ndreturn('nd');// if($j==3)// 3rd, 23rd, 33rd, 253rdreturn('rd');return('th');// everything else will suffixed with 'th' including 0th}
Actualización de código :
Aquí hay una versión modificada que es 14 bytes completos más cortos (107 bytes en total):
function ordinal($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
O, para ser lo más corto posible, 25 bytes más cortos (96 bytes en total):
function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':@['th','st','nd','rd'][$j%10]?:'th');}
Con esta última función, simplemente llame o(121);y hará exactamente lo mismo que las otras funciones que enumeré.
Actualización de Código # 2 :
Ben y yo trabajamos juntos y lo redujimos en 38 bytes (83 bytes en total):
function o($i){return$i.@(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
¡No creemos que pueda ser más corto que esto! Sin embargo, está dispuesto a demostrar que está equivocado. :)
Aquí hay otra versión muy corta que usa las funciones de fecha. Funciona para cualquier número (no limitado por los días del mes) y tiene en cuenta que * 11th * 12th * 13th no sigue el formato * 1st * 2nd * 3rd.
No estoy muy seguro de lo que ofrece esta respuesta además de la respuesta de ChintanThummar. Bueno, insinúa que ChintanThummar cometió una violación de derechos de autor, a menos que haya escrito el código en su fuente ...
Respuestas:
de wikipedia :
¿Dónde
$number
está el número que quieres escribir? Funciona con cualquier número natural.Como una función:
fuente
$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
PHP tiene una funcionalidad incorporada para esto . ¡Incluso maneja la internacionalización!
Tenga en cuenta que esta funcionalidad solo está disponible en PHP 5.3.0 y versiones posteriores.
fuente
NumberFomatter file not found
. ¿Cómo resolviste esto?apt-get install php5-intl
Esto se puede lograr en una sola línea aprovechando una funcionalidad similar en las funciones de fecha / hora integradas de PHP. Humildemente presento:
Solución:
Explicación detallada:
La
date()
función incorporada tiene lógica de sufijo para manejar los cálculos del enésimo día del mes. El sufijo se devuelve cuandoS
se da en la cadena de formato:Dado que
date()
requiere una marca de tiempo (por?
arriba), vamos a pasar nuestro número entero$n
como elday
parámetro amktime()
y el uso de los valores ficticia1
para elhour
,minute
,second
, ymonth
:Esto realmente falla con gracia en valores fuera de rango para un día del mes (es decir
$n > 31
), pero podemos agregar una lógica en línea simple para limitar$n
a 29:El único valor positivo( Mayo de 2017 ) esto falla$n == 0
, pero se soluciona fácilmente agregando 10 en ese caso especial:Actualización, mayo de 2017
Como observó @donatJ, lo anterior falla por encima de 100 (por ejemplo, "111"), ya que las
>=20
comprobaciones siempre devuelven verdadero. Para restablecer estos cada siglo, agregamos un filtro a la comparación:¡Simplemente envuélvelo en una función para mayor comodidad y listo!
fuente
Aquí hay una frase:
Probablemente la solución más corta. Por supuesto, puede estar envuelto por una función:
Saludos, Paul
EDIT1: Corrección de código para 11 a 13.
EDIT2: Corrección de código para 111, 211, ...
EDITAR3: ahora funciona correctamente también para múltiplos de 10.
fuente
de http://www.phpro.org/examples/Ordinal-Suffix.html
fuente
La respuesta simple y fácil será:
fuente
Escribí esto para PHP4. Ha estado funcionando bien y es bastante económico.
fuente
solo necesita aplicar la función dada.
fuente
Genéricamente, puede usar eso y llamar a echo get_placing_string (100);
fuente
Hice una función que no se basa en la
date();
función de PHP, ya que no es necesaria, pero también la hice tan compacta y tan corta como creo que es posible actualmente.El código : (121 bytes en total)
Código más compacto a continuación.
Funciona de la siguiente manera :
Cosas que debes saber sobre esta función :
floor($i)
,round($i)
oceil($i)
al comienzo de la instrucción de retorno final).format_number($i)
al comienzo de la declaración de devolución final para obtener un número entero separado por comas (si está mostrando miles, millones, etc.).$i
del principio de la declaración de devolución si solo desea devolver el sufijo ordinal sin lo que ingresó.Esta función funciona a partir de PHP 5.2, lanzado en noviembre de 2006, simplemente debido a la sintaxis de matriz corta. Si tiene una versión anterior a esta, ¡actualice ya que está casi una década desactualizada! De lo contrario, simplemente reemplace el en línea
['st', 'nd', 'rd']
con una variable temporal que contengaarray('st', 'nd', 'rd');
.La misma función (sin devolver la entrada), pero una vista explosionada de mi función corta para una mejor comprensión:
Actualización de código :
Aquí hay una versión modificada que es 14 bytes completos más cortos (107 bytes en total):
O, para ser lo más corto posible, 25 bytes más cortos (96 bytes en total):
Con esta última función, simplemente llame
o(121);
y hará exactamente lo mismo que las otras funciones que enumeré.Actualización de Código # 2 :
Ben y yo trabajamos juntos y lo redujimos en 38 bytes (83 bytes en total):
¡No creemos que pueda ser más corto que esto! Sin embargo, está dispuesto a demostrar que está equivocado. :)
Espero que todos lo disfruten.
fuente
abs()
con módulo%
abs();
elimina el signo negativo que es lo que necesitaba.Una versión aún más corta para las fechas del mes (hasta 31) en lugar de usar mktime () y no requiere pecl intl:
o procesalmente:
Esto funciona, por supuesto, porque el mes predeterminado que elegí (enero) tiene 31 días.
Curiosamente, si lo prueba con febrero (u otro mes sin 31 días), se reinicia antes del final:
para poder contar hasta los días de este mes con el especificador de fecha
t
en su ciclo: número de días en el mes.fuente
fuente
Encontré una respuesta en PHP.net
fuente
Aquí hay otra versión muy corta que usa las funciones de fecha. Funciona para cualquier número (no limitado por los días del mes) y tiene en cuenta que * 11th * 12th * 13th no sigue el formato * 1st * 2nd * 3rd.
fuente
Aprecio este pequeño fragmento
AQUÍ
fuente