PHP echo calculation with ordinal suffix - php

I'd like to add the following text to a page in Wordpress: "Gina is now in her 16th (or sixteenth) year at the company," where 16th is a calculation based on her start year.
I know how to calculate her number of years at the company using PHP echo:
<?php echo date("Y")-1998 ?>
I also know that there are functions that can be used to attach a suffix to the number, such as:
<?php
$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];
?>
What I don't know how to do is put these two things together and have them output properly on a Wordpress page. My knowledge of PHP is pretty basic so I'm hoping someone out here might have the answer. Thanks!

Well, you said the answer yourself, just put that code together:
<?php
$number = date("Y")-1998;
$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];
echo $abbreviation;
?>
Although I believe the base year would not be date("Y"), but some value fetched from wordpress about Gina.

Related

Does Using Same Declared Variable Name To Make Calculations Make Sense? [duplicate]

This question already has answers here:
Better way to add number to itself?
(9 answers)
Closed 5 years ago.
I'm wondering if this following piece of code makes sense from a PHP perspective:
if(isset($_POST['submit'])){
$year = $_POST['year'];
$month = $_POST['month'];
if($month == 'December'){
$month = 'January';
$year = $year + 1;//can this be done?
}
}
Sure. You could also do:
$year++;
or
$year += 1;
Yes, makes sense and is safe. The right side is evaluated first. There are shortcuts for these operations:
A = A op B
A op= B
So:
$year += 1;
And with everything else as well (-= *= /= .=). For incrementing a single unit, there is also $year++ or $year-- for decrementing, plus the variations ++$year and --$year.
Please check out the manual pages for Assignment Operators and Increment Operators.
Since you're using + operator you're telling php to mathematically sum both values, therefore both of them will be parsed as integer (or float) values before actually making the sum. So if $month's value is "10" (string), it will be parsed as 10 (integer) and then you will have 10 + 1 = 11.

PHP Auto Aging Task for MyBB

So, I was wondering if anybody would mind checking over this task and correcting it? I'm very sure I've muddled Python in with what little PHP I know, and that there are open tags.
Basically, there'll be a field where the nasty decimal age goes ($age, which will later be replaced by the appropriate field id). Our site works in months for juveniles and then years and seasons for adults. Using the nasty age, I'm trying to calculate the rounded age values and then store them as a string value which will then be set as the value of the field that will display the age ($displayagefid, will be replaced later with the appropriate field id). Only certain usergroups will be updated (the list is huge, so I left it out).
I also have no idea how to set a variable as a string using both string and the value of another variable.
Please know that I'm a complete newbie to PHP.
This is intended to run as a task on a self-hosted MyBB forum.
Thank you in advance!
<?php
function task_age($task)
{
global $mybb, $db;
$increment = 0.04167
$age = $age + $increment
floor($age*4) = $seasons
floor($age) = $years
floor($age*12) = $months
if ($year < 1) {
$display_age = $months, "mnths"
}
elseif ( ! filter_var($year, FILTER_VALIDATE_INT) ){
$display_age = $year, "yrs"
}
else {
$display age = $display_age = $years, "yrs", $seasons, "s"
};
$query = $db->query("
UPDATE mybb_userfields userfields
for ($usergroup = a || b || d || all that other crap) {
SET $dispalyagefid = $display_age;
};
");
add_task_log($task, "The age characters task successfully ran.");
I had a cursory look over your code and the first thing which sticks out is you have some of your variable assignments back to front:
$increment = 0.04167
$age = $age + $increment
floor($age*4) = $seasons
floor($age) = $years
floor($age*12) = $months
Whatever is on the left gets set to whatever is on the right, so your first two are OK but the last three need switching around.
Having said that it seems to me you are not approaching this correctly. I enter my decimal age into your site but how are you going to work out seasons? It might be my birthday tomorrow, it might have been my birthday yesterday.
You would be better off having the user enter a date of birth, from that calculate their age.
$birthday=date_create("2013-03-15");
$today=date_create('now');
$diff=date_diff($birthday,$today);
Now in the $diff variable you can check all the elements of a PHP date. So first check if they are under 18:
if ($diff->format("%y") < 18) {
$ageInMonths = ($diff->format("%y") * 12) + $diff->format("%m");
$age = "$ageInMonths months";
}
If they are over 18 you want age in years, then calculate seasons from the remaining months.
else {
$ageInYears = $diff->format("%y");
$ageInSeasons = floor($diff->format("%m") / 4);
if ($ageInSeasons > 0) {
$age = "$ageInYears years and $ageInSeasons seasons";
} else {
$age = "$ageInYears years";
}
}

Ranking with Echo on Php [duplicate]

I want to display numbers as follows
1 as 1st,
2 as 2nd,
...,
150 as 150th.
How should I find the correct ordinal suffix (st, nd, rd or th) for each number in my code?
from wikipedia:
$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];
Where $number is the number you want to write. Works with any natural number.
As a function:
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);
PHP has built-in functionality for this. It even handles internationalization!
$locale = 'en_US';
$nf = new NumberFormatter($locale, NumberFormatter::ORDINAL);
echo $nf->format($number);
Note that this functionality is only available in PHP 5.3.0 and later.
This can be accomplished in a single line by leveraging similar functionality in PHP's built-in date/time functions. I humbly submit:
Solution:
function ordinalSuffix( $n )
{
return date('S',mktime(1,1,1,1,( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
}
Detailed Explanation:
The built-in date() function has suffix logic for handling nth-day-of-the-month calculations. The suffix is returned when S is given in the format string:
date( 'S' , ? );
Since date() requires a timestamp (for ? above), we'll pass our integer $n as the day parameter to mktime() and use dummy values of 1 for the hour, minute, second, and month:
date( 'S' , mktime( 1 , 1 , 1 , 1 , $n ) );
This actually fails gracefully on values out of range for a day of the month (i.e. $n > 31) but we can add some simple inline logic to cap $n at 29:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20))*10 + $n%10) ));
The only positive value(May 2017) this fails on is $n == 0, but that's easily fixed by adding 10 in that special case:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n>=20)+($n==0))*10 + $n%10) ));
Update, May 2017
As observed by #donatJ, the above fails above 100 (e.g. "111st"), since the >=20 checks are always returning true. To reset these every century, we add a filter to the comparison:
date( 'S', mktime( 1, 1, 1, 1, ( (($n>=10)+($n%100>=20)+($n==0))*10 + $n%10) ));
Just wrap it in a function for convenience and off you go!
Here is a one-liner:
$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);
Probably the shortest solution. Can of course be wrapped by a function:
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);
}
Regards,
Paul
EDIT1: Correction of code for 11 through 13.
EDIT2: Correction of code for 111, 211, ...
EDIT3: Now it works correctly also for multiples of 10.
from 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;
}
?>
Simple and Easy Answer will be:
$Day = 3;
echo date("S", mktime(0, 0, 0, 0, $Day, 0));
//OUTPUT - rd
I wrote this for PHP4.
It's been working ok & it's pretty economical.
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';
}
you just need to apply given function.
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';
}
Generically, you can use that and call 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';
}
?>
I made a function that does not rely on the PHP's date(); function as it's not necessary, but also made it as compact and as short as I think is currently possible.
The code: (121 bytes total)
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')));
}
More compact code below.
It works as follows:
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.
Stuff to know about this function:
It deals with negative integers the same as positive integers and keeps the sign.
It returns 11th, 12th, 13th, 811th, 812th, 813th, etc. for the -teen numbers as expected.
It does not check decimals, but will leave them in place (use floor($i), round($i), or ceil($i) at the beginning of the final return statement).
You could also add format_number($i) at the beginning of the final return statement to get a comma-separated integer (if you're displaying thousands, millions, etc.).
You could just remove the $i from the beginning of the return statement if you only want to return the ordinal suffix without what you input.
This function works commencing PHP 5.2 released November 2006 purely because of the short array syntax. If you have a version before this, then please upgrade because you're nearly a decade out of date! Failing that, just replace the in-line ['st', 'nd', 'rd'] with a temporary variable containing array('st', 'nd', 'rd');.
The same function (without returning the input), but an exploded view of my short function for better understanding:
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
}
Code Update:
Here's a modified version that is 14 whole bytes shorter (107 bytes total):
function ordinal($i) {
return $i.(($j=abs($i)%100)>10&&$j<14?'th':#['th','st','nd','rd'][$j%10]?:'th');
}
Or for as short as possible being 25 bytes shorter (96 bytes total):
function o($i){return $i.(($j=abs($i)%100)>10&&$j<14?'th':#['th','st','nd','rd'][$j%10]?:'th');}
With this last function, simply call o(121); and it'll do exactly the same as the other functions I listed.
Code Update #2:
Ben and I worked together and cut it down by 38 bytes (83 bytes total):
function o($i){return$i.#(($j=abs($i)%100)>10&&$j<14?th:[th,st,nd,rd][$j%10]?:th);}
We don't think it can possibly get any shorter than this! Willing to be proven wrong, however. :)
Hope you all enjoy.
An even shorter version for dates in the month (up to 31) instead of using mktime() and not requiring pecl intl:
function ordinal($n) {
return (new DateTime('Jan '.$n))->format('jS');
}
or procedurally:
echo date_format(date_create('Jan '.$n), 'jS');
This works of course because the default month I picked (January) has 31 days.
Interestingly enough if you try it with February (or another month without 31 days), it restarts before the end:
...clip...
31st
1st
2nd
3rd
so you could count up to this month's days with the date specifier t in your loop: number of days in the month.
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;
}
Here is the correct solution
$numberFormatter = new NumberFormatter('en_US', NumberFormatter::ORDINAL);
echo $numberFormatter->format(11);
Found an answer in 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';
}
?>
Here's another very short version using the date functions. It works for any number (not constrained by days of the month) and takes into account that *11th *12th *13th does not follow the *1st *2nd *3rd format.
function getOrdinal($n)
{
return $n . date_format(date_create('Jan ' . ($n % 100 < 20 ? $n % 20 : $n % 10)), 'S');
}
I realise this is an ancient post, however it's probably worth adding that as of PHP 8, the match control structure allows a more concise:
$ordinal = match(in_array(abs($position)%100, [11, 12, 13]) ? 0 : abs($position)%10) { 1 => 'st', 2 => 'nd', 3 => 'rd', default => 'th' };
If you need to append that to the position to get a place:
$place = $position.match(in_array(abs($position)%100, [11, 12, 13]) ? 0 : abs($position)%10) { 1 => 'st', 2 => 'nd', 3 => 'rd', default => 'th' };
You can obviously simplify that out if you know your position will always be positive or less than 11 or whatever.
I fond this small snippet
<?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';
}
?>
HERE

PHP - Showing different text between different dates (3 Different Text to be shown)

I am new to PHP and i want to show 3 different text during different date periods.
e.g. 01/01 - 01/04 = TERM 1, 20/04 - 01/06 = TERM 2, 01/07 - 31/10 = TERM 3.
Can someone help me with that. I have not been able to write a code for that.
Thanking You In Advance.
Regards
Akshat Gupta
Hello Akshat please find the simplified solution below
<?php
$current_date = date('Y-m-d');
if(strtotime($current_date)>strtotime('2015-01-01') && strtotime($current_date)<strtotime('2015-04-01'))
{
echo "TERM 1";
}
elseif(strtotime($current_date)>strtotime('2015-04-20') && strtotime($current_date)<strtotime('2015-06-01'))
{
echo "TERM 2";
}
elseif(strtotime($current_date)>strtotime('2015-07-01') && strtotime($current_date)<strtotime('2015-10-31'))
{
echo "TERM 3";
}
?>
I have tested it and its working fine
you can do it by some if's...
so i write something can so such thing one year one year...for example from now on till next year it'll show term 1 and next year will show term 2 and go on... hope it helps..
<?php
date_default_timezone_set('UTC');
$date = date('Y/m');
echo $date;
if(date('Y')>="2015" && date('Y')<"2016" && date('m') >="02" && date('m')<"03" )
echo "term1";
if(date('Y')>="2016" && date('Y')<"2017" && date('m') >="02" && date('m')<"03" )
echo "term1";
if(date('Y')>="2017" && date('Y')<"2018" && date('m') >="02" && date('m')<"03" )
echo "term1";
i just echo the $date to show you how to get current system time...
the link below will help...
http://php.net/manual/en/function.date.php

if number is a decimal between 2 numbers (php)

I'm writings a PHP script that calculates an average of a number.
EXAMPLE:
$rating = 7;
$votes = 3;
$AvgRating = number_format($rating / $votes,1);
The return $AvgRating for this would be 2.3 (to 1 decimal place).
is it possible to say.....
if ($AvgRating > 2 && $AvgRating < 3){
$display = 'between';
}
echo $display;
I have tried but it does not work, I have tried google but don't know exactly what I need to look for.
This code evaluates correctly...
<?php
$rating = 7;
$votes = 3;
$AvgRating = number_format($rating / $votes,1);
if ($AvgRating > 2 && $AvgRating < 3){
$display = 'between';
}
echo $display;
?>
Hi there is some mistakes $AvgRating retunrs 2.3 not 7.3
So you have to check with this
$rating =7; $votes=3;
$AvgRating = number_format($rating / $votes,1);
if ($AvgRating > 2 && $AvgRating < 3.0){
echo $AvgRating;
}
If your question is whether the condition inside the if statement is correct, yes it is.
However in your case, the if condition fails since the value of $AvgRating (7/3) is less than 7. So you probably might be checking whether $AvgRating is greater than 2.

Categories