Take a value 1-31 and convert it to ordinal date w/ JavaScript

前端 未结 4 1691
清酒与你
清酒与你 2021-01-04 08:13

Is there a JavaScript code snippet to take a value of 1-31 and convert it to 1st, 2nd, 3rd, etc?

Thanks!

相关标签:
4条回答
  • 2021-01-04 08:46
    function getOrdinal(n) {
        var s=["th","st","nd","rd"],
        v=n%100;
        return n+(s[(v-20)%10]||s[v]||s[0]);
    }
    

    Thanks @RobG bit modified version

    function getOrdinal(n) {
        if((parseFloat(n) == parseInt(n)) && !isNaN(n)){
            var s=["th","st","nd","rd"],
            v=n%100;
            return n+(s[(v-20)%10]||s[v]||s[0]);
        }
        return n;     
    }
    

    Tests

    getOrdinal("test");   // test
    getOrdinal(1.5);      // 1.5
    getOrdinal(1);        // 1st
    getOrdinal(2);        // 2nd
    getOrdinal(3);        // 3rd
    getOrdinal(4);        // 4th
    getOrdinal(true);     // true
    getOrdinal(Infinity); // Infinity
    getOrdinal(NaN);      // NaN
    getOrdinal(void 0);   // undefined
    
    0 讨论(0)
  • 2021-01-04 08:51

    You might find it convenient to monkey-patch the function into the Number prototype, so you can call it as a method on the number (implementation shamelessly stolen from Pradeep's answer):

    Number.prototype.toOrdinal = function() {
      var n = this.valueOf(),
          s = [ 'th', 'st', 'nd', 'rd' ],
          v = n % 100;
      return n + (s[(v-20)%10] || s[v] || s[0])
    }
    

    Example use:

    var someDay = Math.floor(Math.random() * 31 + 1);
    alert(someDay.toOrdinal())
    

    Or you may believe that Monkey Patching Is Evil; as usual, YMMV.

    (I sometimes call this particular method th, but that works somewhat better in languages where you don't need the parentheses for invocation.)

    Adding an explanation of the logic. Key points that are Javascript-specific:

    1. The % operator returns negative results for a negative dividend modulo a positive divisor (so -1 % 5 is -1; many other implementations of the modulus operator return only answers between 0 and n-1, so -1 % 5 is 4).
    2. Attempting to index an array by a value outside the valid range of indexes (either negative or past the end of the array) results in the undefined value, which is falsey.

    The logic exploits these facts to return the correct suffix from a compact expression with these parts.

    1. Try to access s[(v-20)%10]. If v (which is the given number modulo 100) is less than 20, then the index is negative and the array access returns undefined. Otherwise, the array index is between 0 and 9. Values 0 through 3 return the correct associated suffix ("th", "st", "nd", and "rd"), while anything greater than 3 will again return undefined.

    2. If the result of 1 is a defined value, return it; otherwise, try to access s[v]. If v is itself 0, 1, 2, or 3, we again get "th", "st", "nd", or "rd" respectively. Otherwise, we get an undefined value, and the expression moves on to the next alternative.

    3. If neither of the above results is defined, we return s[0], which is "th".

    The result is that everything from 4 through 20 - including 11, 12, and 13 - gets a "th", while all other numbers ending in 1, 2, or 3 get "st", "nd", and "rd", respectively.

    0 讨论(0)
  • 2021-01-04 08:56

    Pradeep's answer is cool, but something a bit more robust should test the value and do something sensible if it's not a suitable value for adding an ordinal (like just return the value), e.g.

    var getOrdinal = (function() {
    
        var re = /^\d+$/;
        var ordinal = ["th","st","nd","rd"];
    
        return function (value) {
    
          var t;
    
          if (re.test(String(value))) {
            t = value % 100;
            return t + (ordinal[(t - 20 % 10)] || ordinal[t] || 'th');            
          }
    
          return value;
        }
    }());
    
    getOrdinal( void 0 );  // undefined
    getOrdinal(        );  // undefined
    getOrdinal( NaN    );  // NaN
    getOrdinal( true   );  // true
    getOrdinal( 1.0    );  // 1st
    getOrdinal( ''     );  // '' (empty string)
    getOrdinal(Infinity);  // Infinity
    
    0 讨论(0)
  • 2021-01-04 09:00
    npm install ordinal
    

    Works in both the browser and node. Then just:

    var ordinal = require('ordinal')
    
    ordinal(1);   //=> '1st'
    ordinal(2);   //=> '2nd'
    ordinal(3);   //=> '3rd'
    ordinal(4);   //=> '4th'
    
    ordinal(11);  //=> '11th'
    ordinal(12);  //=> '12th'
    ordinal(13);  //=> '13th'
    
    ordinal(21);  //=> '21st'
    ordinal(22);  //=> '22nd'
    ordinal(23);  //=> '23rd'
    ordinal(24);  //=> '24th'
    

    https://www.npmjs.com/package/ordinal

    0 讨论(0)
提交回复
热议问题