Смотрите мой ответ здесь. stackoverflow.com/questions/69262/… Этот вопрос был для .NET, но я ответил с помощью PHP-решения, поэтому оно должно помочь вам.
nickf
Единственный способ, которым я могу думать о том, чтобы сделать это, это иметь оператор if, увеличивающийся для каждого числа, которое вы можете иметь, т.е. IE, если (1), затем "st" elseif (2), затем "nd" и т. Д. И т. Д., Если (23000) then " й». Это проблема, если у вас большие числа, но вы могли бы написать программу для написания кода для вас, она могла бы зациклить все числа, печатая if для вас, чтобы скопировать + вставить в ваш код.
Том Гуллен
2
@ Том, справочная таблица может быть лучше, просто инициализируйте ее 23000 значениями и получите значение по индексу n, где n - это число, которое вы хотите получить порядковым номером.
Джон Бокер
2
Полковник Шрапнель. Вы можете быть блестящим, но не все. В любом случае спасибо за проявленный интерес к моему вопросу
ArK
@ Джон, очень умная идея, доступ к ней будет очень быстрым, так как каждый индекс представляет число, которое вы ищете.
Хотя поначалу это немного сложно понять, я думаю, что это лучше всего показывает, как работает система порядкового суффикса для английского языка.
Эриско
6
Мне нравится ваше решение. Кроме того, если вы предпочитаете не генерировать 0-е, измените последнюю строку, чтобы быть$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
Gavin Jackson
1
@GavinJackson ваше дополнение к этому отличному решению действительно помогло мне (+1). Не могли бы вы объяснить мне, что происходит в расчете? Я хочу понять. Ура! РЕДАКТИРОВАТЬ: нашел ответ: условный оператор
Эндрю Фокс
Извините, пришлось разбить 111 голосов до 112: D Сделал это функцией в Delphi вместе с демонстрационным приложением: pastebin.com/wvmz1CHY
Джерри Додж
1
@HafezDivandari - ты уверен? Только что протестирован с 7.1.19 и, кажется, работает нормально
Обратите внимание, что это также требует PECL Intl> = 1.0.0
rymo
4
Знаете ли вы, можно ли получить порядковый номер в форме слова? т.е. первый, второй, третий и т. д. вместо 1-го, 2-го, 3-го ...
its_me
@jeremy Когда я пытался использовать NumberFormatter, он всегда выдает ошибку, которая NumberFomatter file not found. Как вы обошли это?
jhnferraris
1
@Jhn вы должны установить расширениеapt-get install php5-intl
Алей
@ Эй, я вижу. У Yii есть встроенный форматер, который мы используем прямо сейчас. хе
джнферрарис
20
Это можно сделать в одной строке, используя аналогичные функции во встроенных функциях даты / времени в PHP. Я смиренно представляю:
Решение:
function ordinalSuffix( $n ){return date('S',mktime(1,1,1,1,((($n>=10)+($n>=20)+($n==0))*10+ $n%10)));}
Детальное объяснение:
Встроенная date()функция имеет суффиксную логику для обработки вычислений n-го числа месяца. Суффикс возвращается, когда Sзадан в строке формата:
date('S',?);
Так date()требует метки времени (для ?выше), мы передадим наше целое число в $nкачестве dayпараметра mktime()и использования фиктивных значений 1для hour, minute, secondи month:
date('S', mktime(1,1,1,1, $n ));
Это фактически терпит неудачу изящно для значений вне диапазона для дня месяца (то есть $n > 31), но мы можем добавить некоторую простую встроенную логику к пределу $nв 29:
Как отмечает @donatJ, вышеупомянутый сбой превышает 100 (например, «111st»), поскольку >=20проверки всегда возвращают true. Чтобы сбросить их каждое столетие, мы добавляем фильтр для сравнения:
Мне нравится такой подход, но, увы, он не работает :-( 30-е выходит как 30-е. 40-е выходит как 40-е. И т. Д.
Flukey
1
Да жаль. Когда я прочитал вопрос, который я подумал, эй, это должно быть возможно с помощью одной строки кода. И я просто напечатал это. Как вы видите из моих правок, я улучшаюсь. После третьего редактирования я думаю, что это уже сделано. По крайней мере, все цифры от 1 до 150 хорошо распечатываются на моем экране.
Пол
Хорошо смотрится до 500! (не проверял это дальше, чем это). Хорошая работа! :-)
Ничего не говорит о датах в вопросе tho. В любом случае я проголосовал - это быстрое и простое решение, когда вы знаете, что диапазон номеров будет <32
cronoklee
8
Я написал это для PHP4. Работает нормально и довольно экономично.
Я сделал функцию, которая не полагается на date();функцию PHP, поскольку она не нужна, но также сделала ее настолько компактной и настолько короткой, насколько я думаю, в настоящее время возможной.
Код : (всего 121 байт)
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')));}
Более компактный код ниже.
Это работает следующим образом :
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.
Материал, чтобы знать об этой функции :
Он работает с отрицательными целыми числами так же, как и с положительными целыми числами, и сохраняет знак.
Он возвращает 11-е, 12-е, 13-е, 811-е, 812-е, 813-е и т. Д. Для 14 чисел, как и ожидалось.
Он не проверяет десятичные, но оставить их на месте (использование floor($i), round($i)или ceil($i)в начале заключительного возвращения заявления).
Вы также можете добавить format_number($i)в начале последнего оператора возврата, чтобы получить целое число через запятую (если вы отображаете тысячи, миллионы и т. Д.).
Вы можете просто удалить $iоператор из начала оператора return, если хотите вернуть только порядковый суффикс без ввода.
Эта функция работает начиная с версии PHP 5.2, выпущенной в ноябре 2006 года, исключительно из-за синтаксиса короткого массива. Если у вас есть версия до этого, пожалуйста, обновите, потому что вы почти на десять лет устарели! В противном случае просто замените встроенную ['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 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}
Обновление кода :
Вот модифицированная версия, которая на 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);}
Мы не думаем, что это может стать короче этого! Желая быть доказанным неправым, как бы то ни было. :)
Вот еще одна очень короткая версия с использованием функций даты. Он работает для любого числа (без ограничений по дням месяца) и учитывает, что * 11 * 12 * 13 не соответствует формату * 1 * 2 * 3.
Я не совсем уверен, что этот ответ предлагает в дополнение к ответу ChintanThummar. Ну, это намекает на то, что ChintanThummar допустил нарушение авторских прав, если только он не написал код в вашем источнике ...
Ответы:
из википедии :
Где
$number
номер, который вы хотите написать. Работает с любым натуральным числом.Как функция:
источник
$abbreviation = ($number)? $number. $ends[$number % 10] : $number;
PHP имеет встроенную функциональность для этого . Это даже обращается с интернационализацией!
Обратите внимание, что эта функциональность доступна только в PHP 5.3.0 и более поздних версиях.
источник
NumberFomatter file not found
. Как вы обошли это?apt-get install php5-intl
Это можно сделать в одной строке, используя аналогичные функции во встроенных функциях даты / времени в PHP. Я смиренно представляю:
Решение:
Детальное объяснение:
Встроенная
date()
функция имеет суффиксную логику для обработки вычислений n-го числа месяца. Суффикс возвращается, когдаS
задан в строке формата:Так
date()
требует метки времени (для?
выше), мы передадим наше целое число в$n
качествеday
параметраmktime()
и использования фиктивных значений1
дляhour
,minute
,second
иmonth
:Это фактически терпит неудачу изящно для значений вне диапазона для дня месяца (то есть
$n > 31
), но мы можем добавить некоторую простую встроенную логику к пределу$n
в 29:Единственное положительное значение( Май 2017 г. ) это не удается$n == 0
, но это легко исправить, добавив 10 в этом особом случае:Обновление, май 2017
Как отмечает @donatJ, вышеупомянутый сбой превышает 100 (например, «111st»), поскольку
>=20
проверки всегда возвращают true. Чтобы сбросить их каждое столетие, мы добавляем фильтр для сравнения:Просто оберните его в функцию для удобства и вперед!
источник
Вот одна строка:
Вероятно, самое короткое решение. Конечно, можно обернуть функцией:
С уважением, Пол
EDIT1: исправление кода для 11-13.
EDIT2: исправление кода для 111, 211, ...
EDIT3: теперь это работает правильно также для кратных 10.
источник
с http://www.phpro.org/examples/Ordinal-Suffix.html
источник
Простой и легкий ответ будет:
источник
Я написал это для PHP4. Работает нормально и довольно экономично.
источник
вам просто нужно применить данную функцию.
источник
В общем, вы можете использовать это и вызвать echo get_placing_string (100);
источник
Я сделал функцию, которая не полагается на
date();
функцию PHP, поскольку она не нужна, но также сделала ее настолько компактной и настолько короткой, насколько я думаю, в настоящее время возможной.Код : (всего 121 байт)
Более компактный код ниже.
Это работает следующим образом :
Материал, чтобы знать об этой функции :
floor($i)
,round($i)
илиceil($i)
в начале заключительного возвращения заявления).format_number($i)
в начале последнего оператора возврата, чтобы получить целое число через запятую (если вы отображаете тысячи, миллионы и т. Д.).$i
оператор из начала оператора return, если хотите вернуть только порядковый суффикс без ввода.Эта функция работает начиная с версии PHP 5.2, выпущенной в ноябре 2006 года, исключительно из-за синтаксиса короткого массива. Если у вас есть версия до этого, пожалуйста, обновите, потому что вы почти на десять лет устарели! В противном случае просто замените встроенную
['st', 'nd', 'rd']
временную переменную, содержащуюarray('st', 'nd', 'rd');
.Та же функция (без возврата входных данных), но в разобранном виде моя короткая функция для лучшего понимания:
Обновление кода :
Вот модифицированная версия, которая на 14 байт короче (всего 107 байт):
Или как можно короче, на 25 байт короче (всего 96 байт):
С этой последней функцией просто вызовите,
o(121);
и она будет делать то же самое, что и другие функции, которые я перечислил.Обновление кода № 2 :
Мы с Беном работали вместе и сократили его на 38 байтов (всего 83 байта):
Мы не думаем, что это может стать короче этого! Желая быть доказанным неправым, как бы то ни было. :)
Надеюсь, вам всем понравится.
источник
abs()
с модулем%
abs();
удаляет отрицательный знак, который мне нужен.Еще более короткая версия для дат в месяце (до 31) вместо использования mktime () и не требующая pecl intl:
или процедурно:
Это работает, конечно, потому что месяц по умолчанию, который я выбрал (январь), имеет 31 день.
Интересно, что если вы попробуете это с февраля (или другого месяца без 31 дня), он перезапускается до конца:
так что вы можете сосчитать дни этого месяца с указателем даты
t
в цикле: количество дней в месяце.источник
источник
Нашел ответ в PHP.net
источник
Вот еще одна очень короткая версия с использованием функций даты. Он работает для любого числа (без ограничений по дням месяца) и учитывает, что * 11 * 12 * 13 не соответствует формату * 1 * 2 * 3.
источник
Я люблю этот маленький фрагмент
ВОТ
источник