There must be a better way to write this

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Robert

    There must be a better way to write this

    Hi,

    I was wanting to write some code to work out whether I needed st, nd rd or
    th in my dates.
    While the code below works, I am certain that there is a better way....

    if (($daterep == "1") || ($daterep == "21") || ($daterep == "31")){
    $letters = "st";
    } elseif (($daterep == "2") || ($daterep == "22")){
    $letters = "nd";
    } elseif (($daterep == "3") || ($daterep == "23")){
    $letters = "rd";
    } else {
    $letters = "th";
    }

    I tried:

    if ($daterep == "1" || "21" || "31") { ... etc

    but it did not work... I don't understand why though?
    I cast $daterep into a string, but now I find that I could have left it
    alone....
    Any suggestions as to how to get this code working a bit smoother?

    Robert


  • Alvaro G. Vicario

    #2
    Re: There must be a better way to write this

    *** Robert escribió/wrote (Sat, 18 Sep 2004 13:03:06 GMT):[color=blue]
    > I was wanting to write some code to work out whether I needed st, nd rd or
    > th in my dates.
    > While the code below works, I am certain that there is a better way....[/color]

    A switch may suit:

    switch($daterep ){
    case '1':
    case '21':
    case '31':
    $letters='st';
    break;
    case '2':
    case '22':
    $letters='nd';
    break;
    case '3':
    case '23':
    $letters='rd';
    break;
    default:
    $letters='th';
    }

    [color=blue]
    > if ($daterep == "1" || "21" || "31") { ... etc
    >
    > but it did not work... I don't understand why though?[/color]

    "21" is not a valid expression. It should be:

    if( ($daterep == "1") || ($daterep == "21") || ($daterep == "31") ){



    In any case, check the manual page for date(), you have format characters
    that make what you want:

    S
    English ordinal suffix for the day of the month, 2 characters
    st, nd, rd or th.

    --
    -+ Álvaro G. Vicario - Burgos, Spain
    +- http://www.demogracia.com (la web de humor barnizada para la intemperie)
    ++ Las dudas informáticas recibidas por correo irán directas a la papelera
    -+ I'm not a free help desk, please don't e-mail me your questions
    --

    Comment

    • Robert

      #3
      Re: There must be a better way to write this

      Thanks Alvaro,

      The case method works well.
      Also I didn't know about the S. It is definatley easy to use!

      My text is missing it! I have found it on the php site now.

      Robert



      "Alvaro G. Vicario" <kAlvaroNOSPAMT HANKS@terra.es> wrote in message
      news:6id4dd3ppp cy$.1uhj805imbl xe.dlg@40tude.n et...[color=blue]
      > *** Robert escribió/wrote (Sat, 18 Sep 2004 13:03:06 GMT):[color=green]
      >> I was wanting to write some code to work out whether I needed st, nd rd
      >> or
      >> th in my dates.
      >> While the code below works, I am certain that there is a better way....[/color]
      >
      > A switch may suit:
      >
      > switch($daterep ){
      > case '1':
      > case '21':
      > case '31':
      > $letters='st';
      > break;
      > case '2':
      > case '22':
      > $letters='nd';
      > break;
      > case '3':
      > case '23':
      > $letters='rd';
      > break;
      > default:
      > $letters='th';
      > }
      >
      >[color=green]
      >> if ($daterep == "1" || "21" || "31") { ... etc
      >>
      >> but it did not work... I don't understand why though?[/color]
      >
      > "21" is not a valid expression. It should be:
      >
      > if( ($daterep == "1") || ($daterep == "21") || ($daterep == "31") ){
      >
      >
      >
      > In any case, check the manual page for date(), you have format characters
      > that make what you want:
      >
      > S
      > English ordinal suffix for the day of the month, 2 characters
      > st, nd, rd or th.
      >
      > --
      > -+ Álvaro G. Vicario - Burgos, Spain
      > +- http://www.demogracia.com (la web de humor barnizada para la
      > intemperie)
      > ++ Las dudas informáticas recibidas por correo irán directas a la papelera
      > -+ I'm not a free help desk, please don't e-mail me your questions
      > --[/color]


      Comment

      • R. Rajesh Jeba Anbiah

        #4
        Re: There must be a better way to write this

        Robert wrote:[color=blue]
        > if (($daterep == "1") || ($daterep == "21") || ($daterep == "31")){
        > $letters = "st";
        > } elseif (($daterep == "2") || ($daterep == "22")){
        > $letters = "nd";
        > } elseif (($daterep == "3") || ($daterep == "23")){
        > $letters = "rd";
        > } else {
        > $letters = "th";
        > }[/color]

        Perhaps a lookup table:
        $map[1] = 'st';
        $map[21] = 'st';
        $map[31] = 'st';
        $map[2] = 'nd';
        ....

        --
        | Just another PHP saint |
        Email: rrjanbiah-at-Y!com

        Comment

        • Robert

          #5
          Re: There must be a better way to write this

          Good Idea,

          But then I'd have to put in an item for every day wouldn't I?

          Say I wanted the leetters for the 15th.....

          Robert

          "R. Rajesh Jeba Anbiah" <ng4rrjanbiah@r ediffmail.com> wrote in message
          news:1095515362 .325880.301070@ k26g2000oda.goo glegroups.com.. .[color=blue]
          > Robert wrote:[color=green]
          >> if (($daterep == "1") || ($daterep == "21") || ($daterep == "31")){
          >> $letters = "st";
          >> } elseif (($daterep == "2") || ($daterep == "22")){
          >> $letters = "nd";
          >> } elseif (($daterep == "3") || ($daterep == "23")){
          >> $letters = "rd";
          >> } else {
          >> $letters = "th";
          >> }[/color]
          >
          > Perhaps a lookup table:
          > $map[1] = 'st';
          > $map[21] = 'st';
          > $map[31] = 'st';
          > $map[2] = 'nd';
          > ...
          >
          > --
          > | Just another PHP saint |
          > Email: rrjanbiah-at-Y!com
          >[/color]


          Comment

          • Andy Hassall

            #6
            Re: There must be a better way to write this

            On Sat, 18 Sep 2004 15:19:36 +0200, "Alvaro G. Vicario"
            <kAlvaroNOSPAMT HANKS@terra.es> wrote:
            [color=blue][color=green]
            >> if ($daterep == "1" || "21" || "31") { ... etc
            >>
            >> but it did not work... I don't understand why though?[/color]
            >
            >"21" is not a valid expression. It should be:[/color]

            "21" is certainly a valid expression, it's a non-empty, non-"0" string, which
            in a Boolean context becomes bool(true).

            if ($daterep == "1" || "21" || "31")
            ->
            if ($daterep == true)
            ->
            if ($daterep)

            So if $daterep is non-zero and non-empty, the condition is always true.
            [color=blue]
            >if( ($daterep == "1") || ($daterep == "21") || ($daterep == "31") ){[/color]

            Clearly this is what the OP meant to do, but "21" is still an expression.

            --
            Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
            <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

            Comment

            • Andy Hassall

              #7
              Re: There must be a better way to write this

              On Sat, 18 Sep 2004 13:03:06 GMT, "Robert" <lonerngraus@ya hoo.com.au> wrote:
              [color=blue]
              >I was wanting to write some code to work out whether I needed st, nd rd or
              >th in my dates.
              >While the code below works, I am certain that there is a better way....
              >
              >if (($daterep == "1") || ($daterep == "21") || ($daterep == "31")){
              > $letters = "st";
              >} elseif (($daterep == "2") || ($daterep == "22")){
              > $letters = "nd";
              >} elseif (($daterep == "3") || ($daterep == "23")){
              > $letters = "rd";
              >} else {
              > $letters = "th";
              >}
              >
              >I tried:
              >
              >if ($daterep == "1" || "21" || "31") { ... etc
              >
              >but it did not work... I don't understand why though?
              >I cast $daterep into a string, but now I find that I could have left it
              >alone....
              >Any suggestions as to how to get this code working a bit smoother?[/color]

              <?php
              function ordinal($n)
              {
              $ordinalSuffix = array('th', 'st', 'nd', 'rd', 'th',
              'th', 'th', 'th', 'th', 'th');
              if ($n >= 10 && $n <= 19)
              return $n . 'th';
              else
              return $n . $ordinalSuffix[$n % 10];
              }

              for ($i = 1; $i <= 31; $i++)
              {
              print ordinal($i) . '<br>';
              }
              ?>

              --
              Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
              <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

              Comment

              • Alvaro G. Vicario

                #8
                Re: There must be a better way to write this

                *** Andy Hassall escribió/wrote (Sat, 18 Sep 2004 15:20:28 +0100):[color=blue]
                > "21" is certainly a valid expression[/color]

                Of course, you are right.

                --
                -+ Álvaro G. Vicario - Burgos, Spain
                +- http://www.demogracia.com (la web de humor barnizada para la intemperie)
                ++ Las dudas informáticas recibidas por correo irán directas a la papelera
                -+ I'm not a free help desk, please don't e-mail me your questions
                --

                Comment

                • Michael Fesser

                  #9
                  Re: There must be a better way to write this

                  .oO(Robert)
                  [color=blue]
                  >Good Idea,
                  >
                  >But then I'd have to put in an item for every day wouldn't I?
                  >
                  >Say I wanted the leetters for the 15th.....[/color]

                  With the modulo-operator you can get the last digit (mod 10):

                  $last = $value % 10;

                  For $value = 15 this would be 5. A lookup-table could look like this:

                  $map[0] = 'th';
                  $map[1] = 'st';
                  $map[2] = 'nd';
                  $map[3] = 'rd';

                  You would simply have to check if there's a key in that table for the
                  last digit, if not use the element with the key 0 ('th').

                  Only little problem are numbers ending on 11, 12 or 13, they need a
                  special treatment.

                  Another simple algorithm is described in



                  A possible quick 'n dirty implementation, using both algorithms:

                  $lookup = array('th', 'st', 'nd', 'rd');
                  $letters = ($value / 10 % 10) != 1
                  ? isset($lookup[$last = $value % 10]) ? $lookup[$last] : $lookup[0]
                  : $lookup[0];

                  This should work for all numbers, but if you only have to take care of
                  dates the date() function should be fine.

                  Micha

                  Comment

                  • Robert Stearns

                    #10
                    Re: There must be a better way to write this

                    Robert wrote:[color=blue]
                    > Hi,
                    >
                    > I was wanting to write some code to work out whether I needed st, nd rd or
                    > th in my dates.
                    > While the code below works, I am certain that there is a better way....
                    >
                    > if (($daterep == "1") || ($daterep == "21") || ($daterep == "31")){
                    > $letters = "st";
                    > } elseif (($daterep == "2") || ($daterep == "22")){
                    > $letters = "nd";
                    > } elseif (($daterep == "3") || ($daterep == "23")){
                    > $letters = "rd";
                    > } else {
                    > $letters = "th";
                    > }
                    >
                    > I tried:
                    >
                    > if ($daterep == "1" || "21" || "31") { ... etc
                    >
                    > but it did not work... I don't understand why though?
                    > I cast $daterep into a string, but now I find that I could have left it
                    > alone....
                    > Any suggestions as to how to get this code working a bit smoother?
                    >
                    > Robert
                    >
                    >[/color]
                    A little math is in order:
                    $daterepl = $daterep % 10;
                    switch ($daterepl) {
                    case 1:
                    $letters="st";
                    break;
                    case 2:
                    $letters="nd";
                    break;
                    case 3:
                    $letters="rd";
                    break;
                    default:
                    $letters="th";
                    }
                    A nice side effect of this is that it will work for any (positive) integer.

                    Comment

                    • Andy Hassall

                      #11
                      Re: There must be a better way to write this

                      On Sat, 18 Sep 2004 13:02:44 -0400, Robert Stearns <rstearns1241@c harter.net>
                      wrote:
                      [color=blue]
                      >A little math is in order:
                      >$daterepl = $daterep % 10;
                      >switch ($daterepl) {
                      > case 1:
                      > $letters="st";
                      > break;
                      > case 2:
                      > $letters="nd";
                      > break;
                      > case 3:
                      > $letters="rd";
                      > break;
                      > default:
                      > $letters="th";
                      >}
                      >A nice side effect of this is that it will work for any (positive) integer.[/color]

                      11st, 12nd, 13rd...

                      --
                      Andy Hassall / <andy@andyh.co. uk> / <http://www.andyh.co.uk >
                      <http://www.andyhsoftwa re.co.uk/space> Space: disk usage analysis tool

                      Comment

                      • Nikolai Chuvakhin

                        #12
                        Re: There must be a better way to write this

                        "Robert" <lonerngraus@ya hoo.com.au> wrote in message
                        news:<emW2d.350 62$D7.7240@news-server.bigpond. net.au>...[color=blue]
                        >
                        > I was wanting to write some code to work out whether I needed st,
                        > nd rd or th in my dates.[/color]

                        $date = strtotime('2004-09-22');
                        echo date('F jS', $date); // prints "September 22nd"

                        Cheers,
                        NC

                        Comment

                        • Fox

                          #13
                          Re: There must be a better way to write this



                          Robert wrote:[color=blue]
                          > Hi,
                          >
                          > I was wanting to write some code to work out whether I needed st, nd rd or
                          > th in my dates.
                          > While the code below works, I am certain that there is a better way....
                          >
                          > if (($daterep == "1") || ($daterep == "21") || ($daterep == "31")){
                          > $letters = "st";
                          > } elseif (($daterep == "2") || ($daterep == "22")){
                          > $letters = "nd";
                          > } elseif (($daterep == "3") || ($daterep == "23")){
                          > $letters = "rd";
                          > } else {
                          > $letters = "th";
                          > }
                          >
                          > I tried:
                          >
                          > if ($daterep == "1" || "21" || "31") { ... etc
                          >
                          > but it did not work... I don't understand why though?
                          > I cast $daterep into a string, but now I find that I could have left it
                          > alone....
                          > Any suggestions as to how to get this code working a bit smoother?
                          >
                          > Robert
                          >
                          >[/color]

                          here's my 2cents worth:

                          function
                          numToOrdinal($n um)
                          {
                          $n = $num % 100;
                          $suff = array("th", "st", "nd", "rd", "th"); // suff for suffix
                          $ord = $n<21?($n<4 ? $suff[$n]:$suff[0]): ($n%10>4 ? $suff[0] : $suff[$n%10]);
                          return $num . $ord;
                          }


                          for($i = 0; $i < 200; $i++)
                          {
                          echo numToOrdinal($i ) . "<br>";
                          }


                          handles 0th and all positive integers.

                          [error checking should be implemented]

                          Fox
                          ***************





                          Comment

                          Working...