How can I pad a value with leading zeros?

337.1k Views Asked by At

What is the recommended way to zerofill a value in JavaScript? I imagine I could build a custom function to pad zeros on to a typecasted value, but I'm wondering if there is a more direct way to do this?

Note: By "zerofilled" I mean it in the database sense of the word (where a 6-digit zerofilled representation of the number 5 would be "000005").

78

There are 78 best solutions below

1
On BEST ANSWER

Since ECMAScript 2017 we have padStart:

const padded = (.1 + "").padStart(6, "0");
console.log(`-${padded}`);

Before ECMAScript 2017

With toLocaleString:

var n=-0.1;
var res = n.toLocaleString('en', {minimumIntegerDigits:4,minimumFractionDigits:2,useGrouping:false});
console.log(res);

12
On

I can't believe all the complex answers on here... Just use this:

var zerofilled = ('0000'+n).slice(-4);

let n = 1
var zerofilled = ('0000'+n).slice(-4);
console.log(zerofilled)

0
On

I didn't see anyone point out the fact that when you use String.prototype.substr() with a negative number it counts from the right.

A one liner solution to the OP's question, a 6-digit zerofilled representation of the number 5, is:

console.log(("00000000" + 5).substr(-6));

Generalizing we'll get:

function pad(num, len) { return ("00000000" + num).substr(-len) };

console.log(pad(5, 6));
console.log(pad(45, 6));
console.log(pad(345, 6));
console.log(pad(2345, 6));
console.log(pad(12345, 6));

1
On

After a, long, long time of testing 15 different functions/methods found in this questions answers, I now know which is the best (the most versatile and quickest).

I took 15 functions/methods from the answers to this question and made a script to measure the time taken to execute 100 pads. Each pad would pad the number 9 with 2000 zeros. This may seem excessive, and it is, but it gives you a good idea about the scaling of the functions.

The code I used can be found here: https://gist.github.com/NextToNothing/6325915

Feel free to modify and test the code yourself.

In order to get the most versatile method, you have to use a loop. This is because with very large numbers others are likely to fail, whereas, this will succeed.

So, which loop to use? Well, that would be a while loop. A for loop is still fast, but a while loop is just slightly quicker(a couple of ms) - and cleaner.

Answers like those by Wilco, Aleksandar Toplek or Vitim.us will do the job perfectly.

Personally, I tried a different approach. I tried to use a recursive function to pad the string/number. It worked out better than methods joining an array but, still, didn't work as quick as a for loop.

My function is:

function pad(str, max, padder) {
  padder = typeof padder === "undefined" ? "0" : padder;
  return str.toString().length < max ? pad(padder.toString() + str, max, padder) : str;
}

You can use my function with, or without, setting the padding variable. So like this:

pad(1, 3); // Returns '001'
// - Or -
pad(1, 3, "x"); // Returns 'xx1'

Personally, after my tests, I would use a method with a while loop, like Aleksandar Toplek or Vitim.us. However, I would modify it slightly so that you are able to set the padding string.

So, I would use this code:

function padLeft(str, len, pad) {
    pad = typeof pad === "undefined" ? "0" : pad + "";
    str = str + "";
    while(str.length < len) {
        str = pad + str;
    }
    return str;
}

// Usage
padLeft(1, 3); // Returns '001'
// - Or -
padLeft(1, 3, "x"); // Returns 'xx1'

You could also use it as a prototype function, by using this code:

Number.prototype.padLeft = function(len, pad) {
    pad = typeof pad === "undefined" ? "0" : pad + "";
    var str = this + "";
    while(str.length < len) {
        str = pad + str;
    }
    return str;
}

// Usage
var num = 1;

num.padLeft(3); // Returns '001'
// - Or -
num.padLeft(3, "x"); // Returns 'xx1'
1
On

I use this snippet to get a five-digits representation:

(value+100000).toString().slice(-5) // "00123" with value=123
0
On

To pad at the end of the number, use num.toFixed

for example:

  document.getElementById('el').value = amt.toFixed(2);

It's the simplest solution i've found, and it works.

0
On

Here are five different ways to zero-fill a number in JavaScript:

  1. String.prototype.padStart():

    let n = 1;
    let zerofilled = n.toString().padStart(6, '0');
    console.log(zerofilled);
    
  2. String concatenation and slice:

    let n = 1;
    let zerofilled = ('000000' + n).slice(-6);
    console.log(zerofilled);
    
  3. String repeat:

    let n = 1;
    let zerofilled = '0'.repeat(6 - n.toString().length) + n;
    console.log(zerofilled);
    
  4. Convert to string and pad with Array join:

    let n = 1;
    let zerofilled = Array(7).join('0') + n;
    console.log(zerofilled.slice(-6));
    
  5. Convert to string and pad with Array fill:

    let n = 1;
    let zerofilled = (Array(6).fill('0').join('') + n).slice(-6);
    console.log(zerofilled);
    

Each of these solutions achieves zero-filling, and the best one depends on factors like readability, performance, and personal preference in the context of your specific use case.

0
On

A simple one for my use case (to fill milliseconds never > 999) You can adjust the number of zeros for yours or use a more generic way if required.

/**
 * @val integer
 * @zeros padding
 */
function zeroFill(val, zeros)
{
    var str = val.toString();
    if (str.length >= zeros)
        return str;
    str = "000" + str;
    return str.substring(str.length - zeros);
}
1
On

Use:

function zfill(num, len) {
  return(0 > num ? "-" : "") + (Math.pow(10, len) <= Math.abs(num) ? "0" + Math.abs(num) : Math.pow(10, len) + Math.abs(num)).toString().substr(1)
}

This handles negatives and situations where the number is longer than the field width. And floating-point.

0
On
function uint_zerofill(num, width) {
    var pad = ''; num += '';
    for (var i = num.length; i < width; i++)
        pad += '0';
    return pad + num;
}
0
On

A little math can give you a one-line function:

function zeroFill( number, width ) {
  return Array(width - parseInt(Math.log(number)/Math.LN10) ).join('0') + number;
}

That's assuming that number is an integer no wider than width. If the calling routine can't make that guarantee, the function will need to make some checks:

function zeroFill( number, width ) {
    var n = width - parseInt(Math.log(number)/Math.LN10);
    return (n < 0) ? '' + number : Array(n).join('0') + number;
}
1
On

The latest way to do this is much simpler:

var number = 2
number.toLocaleString(undefined, {minimumIntegerDigits:2})

output: "02"

1
On

With ES6+ JavaScript:

You can "zerofill a number" with something like the following function:

/**
 * @param number The number
 * @param minLength Minimal length for your string with leading zeroes
 * @return Your formatted string
 */
function zerofill(nb, minLength) {
    // Convert your number to string.
    let nb2Str = nb.toString()

    // Guess the number of zeroes you will have to write.
    let nbZeroes = Math.max(0, minLength - nb2Str.length)

    // Compute your result.
    return `${ '0'.repeat(nbZeroes) }${ nb2Str }`
}

console.log(zerofill(5, 6))    // Displays "000005"

With ES2017+:

/**
 * @param number The number
 * @param minLength Minimal length for your string with leading zeroes
 * @return Your formatted string
 */
const zerofill = (nb, minLength) => nb.toString().padStart(minLength, '0')

console.log(zerofill(5, 6))    // Displays "000005"
1
On

This is the ES6 solution.

function pad(num, len) {
  return '0'.repeat(len - num.toString().length) + num;
}
alert(pad(1234,6));

10
On

Here's what I used to pad a number up to 7 characters.

("0000000" + number).slice(-7)

This approach will probably suffice for most people.

Edit: If you want to make it more generic you can do this:

("0".repeat(padding) + number).slice(-padding)

Edit 2: Note that since ES2017 you can use String.prototype.padStart:

number.toString().padStart(padding, "0")
0
On

My contribution:

I'm assuming you want the total string length to include the 'dot'. If not it's still simple to rewrite to add an extra zero if the number is a float.

padZeros = function (num, zeros) {
        return (((num < 0) ? "-" : "") + Array(++zeros - String(Math.abs(num)).length).join("0") + Math.abs(num));
    }
0
On

If npm is available in your environment some of ready-made packages can be used: www.npmjs.com/browse/keyword/zeropad.

I like zero-fill.

Installation

$ npm install zero-fill

Usage

var zeroFill = require('zero-fill')

zeroFill(4, 1)      // '0001' 
zeroFill(4, 1, '#') // '###1' custom padding
zeroFill(4)(1)      // '0001' partials
2
On

Use recursion:

function padZero(s, n) {
    s = s.toString(); // In case someone passes a number
    return s.length >= n ? s : padZero('0' + s, n);
}
0
On

The simplest, most straight-forward solution you will find.

function zerofill(number,length) {
    var output = number.toString();
    while(output.length < length) {
      output = '0' + output;
    }
    return output;
}
1
On

I wrote something in ECMAScript 6 (TypeScript) and perhaps someone can use it:

class Helper {
    /**
     * adds leading 0 and returns string if value is not minSize long,
     * else returns value as string
     *
     * @param {string|number} value
     * @param {number} minSize
     * @returns {string}
     */
    public static leadingNullString(value: string|number, minSize: number): string {
        if (typeof value == "number") {
            value = "" + value;
        }
        let outString: string = '';
        let counter: number = minSize - value.length;
        if (counter > 0) {
            for (let i = 0; i < counter; i++) {
                outString += '0';
            }
        }
        return (outString + value);
    }
}

Helper.leadingNullString(123, 2); returns "123"

Helper.leadingNullString(5, 2); returns "05"

Helper.leadingNullString(40,2); returns "40"

The ecmaScript4 (JavaScript) transpilation looks like that:

var Helper = (function () {
    function Helper() {
    }
    Helper.leadingNullString = function (value, minSize) {
        if (typeof value == "number") {
            value = "" + value;
        }
        var outString = '';
        var counter = minSize - value.length;
        if (counter > 0) {
            for (var i = 0; i < counter; i++) {
                outString += '0';
            }
        }
        return (outString + value);
    };
    return Helper;
}());
0
On

This can be easily achieved with Intl.NumberFormat function:

const num = 5;
const formattedNum = new Intl.NumberFormat('en', { minimumIntegerDigits: 6, useGrouping: false }).format(num);
console.log(formattedNum);

0
On

First parameter is any real number, second parameter is a positive integer specifying the minimum number of digits to the left of the decimal point and third parameter is an optional positive integer specifying the number if digits to the right of the decimal point.

function zPad(n, l, r){
    return(a=String(n).match(/(^-?)(\d*)\.?(\d*)/))?a[1]+(Array(l).join(0)+a[2]).slice(-Math.max(l,a[2].length))+('undefined'!==typeof r?(0<r?'.':'')+(a[3]+Array(r+1).join(0)).slice(0,r):a[3]?'.'+a[3]:''):0
}

so

           zPad(6, 2) === '06'
          zPad(-6, 2) === '-06'
       zPad(600.2, 2) === '600.2'
        zPad(-600, 2) === '-600'
         zPad(6.2, 3) === '006.2'
        zPad(-6.2, 3) === '-006.2'
      zPad(6.2, 3, 0) === '006'
        zPad(6, 2, 3) === '06.000'
    zPad(600.2, 2, 3) === '600.200'
zPad(-600.1499, 2, 3) === '-600.149'
0
On
function zeroFill(number, width) {
    width -= (number.toString().length - /\./.test(number));
    if (width > 0) {
        return new Array(width + 1).join('0') + number;
    }
    return number + ""; // always return a string
}

Slight changes made to Peter's code. With his code if the input is (1.2, 3) the value returned should be 01.2 but it is returning 1.2. The changes here should correct that.

3
On
function pad(toPad, padChar, length){
    return (String(toPad).length < length)
        ? new Array(length - String(toPad).length + 1).join(padChar) + String(toPad)
        : toPad;
}

pad(5, 0, 6) = 000005

pad('10', 0, 2) = 10 // don't pad if not necessary

pad('S', 'O', 2) = SO

...etc.

Cheers

0
On

Variable-length padding function:

function addPaddingZeroes(value, nLength)
{
    var sValue = value + ''; // Converts to string

    if(sValue.length >= nLength)
        return sValue;
    else
    {
        for(var nZero = 0; nZero < nLength; nZero++)
            sValue = "0" + sValue;
        return (sValue).substring(nLength - sValue.length, nLength);
    }
}
8
On

I actually had to come up with something like this recently. I figured there had to be a way to do it without using loops.

This is what I came up with.

function zeroPad(num, numZeros) {
    var n = Math.abs(num);
    var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
    var zeroString = Math.pow(10,zeros).toString().substr(1);
    if( num < 0 ) {
        zeroString = '-' + zeroString;
    }

    return zeroString+n;
}

Then just use it providing a number to zero pad:

> zeroPad(50,4);
"0050"

If the number is larger than the padding, the number will expand beyond the padding:

> zeroPad(51234, 3);
"51234"

Decimals are fine too!

> zeroPad(51.1234, 4);
"0051.1234"

If you don't mind polluting the global namespace you can add it to Number directly:

Number.prototype.leftZeroPad = function(numZeros) {
    var n = Math.abs(this);
    var zeros = Math.max(0, numZeros - Math.floor(n).toString().length );
    var zeroString = Math.pow(10,zeros).toString().substr(1);
    if( this < 0 ) {
        zeroString = '-' + zeroString;
    }

    return zeroString+n;
}

And if you'd rather have decimals take up space in the padding:

Number.prototype.leftZeroPad = function(numZeros) {
    var n = Math.abs(this);
    var zeros = Math.max(0, numZeros - n.toString().length );
    var zeroString = Math.pow(10,zeros).toString().substr(1);
    if( this < 0 ) {
        zeroString = '-' + zeroString;
    }

    return zeroString+n;
}

Cheers!



XDR came up with a logarithmic variation that seems to perform better.

WARNING: This function fails if num equals zero (e.g. zeropad(0, 2))

function zeroPad (num, numZeros) {
    var an = Math.abs (num);
    var digitCount = 1 + Math.floor (Math.log (an) / Math.LN10);
    if (digitCount >= numZeros) {
        return num;
    }
    var zeroString = Math.pow (10, numZeros - digitCount).toString ().substr (1);
    return num < 0 ? '-' + zeroString + an : zeroString + an;
}

Speaking of performance, tomsmeding compared the top 3 answers (4 with the log variation). Guess which one majorly outperformed the other two? :)

8
On

Here's a quick function I came up with to do the job. If anyone has a simpler approach, feel free to share!

function zerofill(number, length) {
    // Setup
    var result = number.toString();
    var pad = length - result.length;

    while(pad > 0) {
        result = '0' + result;
        pad--;
    }

    return result;
}
0
On

This method isn't faster, but it's fairly native.

zeroPad = function (num, count) {
    return [Math.pow(10, count - num.toString().length), num].join('').substr(1);
};
1
On
function zeroPad(num,digits){ return ((num/Math.pow(10,digits))+'').slice(2) } 
1
On

This one is less native, but may be the fastest...

zeroPad = function (num, count) {
    var pad = (num + '').length - count;
    while(--pad > -1) {
        num = '0' + num;
    }
    return num;
};
0
On

Our tests were bogus because mine had a typo.

zeroPad = function (num, count) {
    return ((num / Math.pow(10, count)) + '').substr(2);
};

Paul's is the fastest, but I think .substr is faster than .slice even if it is one character more ;)

2
On

Some monkeypatching also works

String.prototype.padLeft = function (n, c) {
  if (isNaN(n))
    return null;
  c = c || "0";
  return (new Array(n).join(c).substring(0, this.length-n)) + this; 
};
var paddedValue = "123".padLeft(6); // returns "000123"
var otherPadded = "TEXT".padLeft(8, " "); // returns "    TEXT"
0
On

Posting in case this is what you are looking for, converts time remaining in milliseconds to a string like 00:04:21

function showTimeRemaining(remain){
  minute = 60 * 1000;
  hour = 60 * minute;
  //
  hrs = Math.floor(remain / hour);
  remain -= hrs * hour;
  mins = Math.floor(remain / minute);
  remain -= mins * minute;
  secs = Math.floor(remain / 1000);
  timeRemaining = hrs.toString().padStart(2, '0') + ":" + mins.toString().padStart(2, '0') + ":" + secs.toString().padStart(2, '0');
  return timeRemaining;
}
0
On

Just for fun, here's my version of a pad function:

function pad(num, len) {
  return Array(len + 1 - num.toString().length).join('0') + num;
}

It also won't truncate numbers longer than the padding length

1
On

I often use this construct for doing ad-hoc padding of some value n, known to be a positive, decimal:

(offset + n + '').substr(1);

Where offset is 10^^digits.

E.g., padding to 5 digits, where n = 123:

(1e5 + 123 + '').substr(1); // => 00123

The hexadecimal version of this is slightly more verbose:

(0x100000 + 0x123).toString(16).substr(1); // => 00123

Note 1: I like @profitehlolz's solution as well, which is the string version of this, using slice()'s nifty negative-index feature.

2
On

Don't reinvent the wheel; use underscore string:

jsFiddle

var numToPad = '5';

alert(_.str.pad(numToPad, 6, '0')); // Yields: '000005'
0
On

My little contribution with this topic (https://gist.github.com/lucasferreira/a881606894dde5568029):

/* Autor: Lucas Ferreira - http://blog.lucasferreira.com | Usage: fz(9) or fz(100, 7) */
function fz(o, s) {
    for(var s=Math.max((+s||2),(n=""+Math.abs(o)).length); n.length<s; (n="0"+n));
    return (+o < 0 ? "-" : "") + n;
};

Usage:

fz(9) & fz(9, 2) == "09"
fz(-3, 2) == "-03"
fz(101, 7) == "0000101"

I know, it's a pretty dirty function, but it's fast and works even with negative numbers ;)

0
On
function zFill(n,l){
    return 
      (l > n.toString().length) ? 
        ( (Array(l).join('0') + n).slice(-l) ) : n;
}
0
On

sprintf.js is a complete open source JavaScript sprintf implementation for the browser and node.js.

Its prototype is simple:

string sprintf(string format , [mixed arg1 [, mixed arg2 [ ,...]]])

I'd like to recommend sprintf module from Alexandru Mărășteanu throughout the solution would simply looks like:

var sprintf = require('sprintf');
var zeroFilled = sprintf('%06d', 5);

console.log(zeroFilled); // 000005

Note: I'm answering this question 6 years later but it seems that this question becomes a "javascript zero leading" reference considering it's high number of views and answers.

0
On

just wanted to make the comment (but i don't have enough points) that the highest voted answer fails with negative numbers and decimals

function padNumber(n,pad) {
    p = Math.pow(10,pad);
    a = Math.abs(n);
    g = (n<0);
    return (a < p) ?  ((g ? '-' : '') + (p+a).toString().substring(1)) : n;
}

padNumber( -31.235, 5);

"-00031.235"
0
On

Here a little array solution within a two line function. It checks also if the leading zeros are less than the length of the number string.

function pad(num, z) {
    if (z < (num = num + '').length) return num;
    return Array(++z - num.length).join('0') + num;
}
1
On

Maybe I am to naive, but I think that this works in one simple and efficient line of code (for positive numbers):

padded = (value + Math.pow(10, total_length) + "").slice(1)

As long as you keep your length OK according to you set of values (as in any zero padding), this should work.

The steps are:

  1. Add the power of 10 with the correct number of 0's [69+1000 = 1069]
  2. Convert to string with +"" [1069 => "1069"]
  3. Slice the first 1, which resulted of first multiplication ["1069" => "069"]

For natural listings (files, dirs...) is quite useful.

0
On

The following provides a quick and fast solution:

function numberPadLeft(num , max, padder = "0"){
     return "" == (num += "") ? "" :
     ( dif = max - num.length, dif > 0 ?
     padder.repeat(dif < 0 ? 0 : dif) + num :
     num )
}

3
On

If the fill number is known in advance not to exceed a certain value, there's another way to do this with no loops:

var fillZeroes = "00000000000000000000";  // max number of zero fill ever asked for in global

function zeroFill(number, width) {
    // make sure it's a string
    var input = number + "";  
    var prefix = "";
    if (input.charAt(0) === '-') {
        prefix = "-";
        input = input.slice(1);
        --width;
    }
    var fillAmt = Math.max(width - input.length, 0);
    return prefix + fillZeroes.slice(0, fillAmt) + input;
}

Test cases here: http://jsfiddle.net/jfriend00/N87mZ/

0
On

A silly recursive way is:

function paddingZeros(text, limit) {
  if (text.length < limit) {
    return paddingZeros("0" + text, limit);
  } else {
    return text;
  }
}

where the limit is the size you want the string to be.

Ex: appendZeros("7829", 20) // 00000000000000007829

2
On

The quick and dirty way:

y = (new Array(count + 1 - x.toString().length)).join('0') + x;

For x = 5 and count = 6 you'll have y = "000005"

0
On
exports.pad = (num, length) => "0".repeat(length - num.toString().length) + num;
0
On

I found the problem interesting, I put my small contribution

function zeroLeftComplete(value, totalCharters = 3) {
    const valueString = value.toString() || '0'
    const zeroLength = valueString.length - totalCharters
    if (Math.sign(parseInt(zeroLength)) === -1) {
        const zeroMissing = Array.from({ length: Math.abs(zeroLength) }, () => '0').join('')
        return `${zeroMissing}${valueString}`
    } else return valueString

};
console.log(zeroLeftComplete(0));
console.log(zeroLeftComplete(1));
console.log(zeroLeftComplete(50));
console.log(zeroLeftComplete(50561,3));

0
On

I didn't see any answer in this form so here my shot with regex and string manipulation

(Works also for negative and decimal numbers)

Code:

function fillZeroes(n = 0, m = 1) {
  const p = Math.max(1, m);
  return String(n).replace(/\d+/, x => '0'.repeat(Math.max(p - x.length, 0)) + x);
}

Some outputs:

console.log(fillZeroes(6, 2))          // >> '06'
console.log(fillZeroes(1.35, 2))       // >> '01.35'
console.log(fillZeroes(-16, 3))        // >> '-016'
console.log(fillZeroes(-1.456, 3))     // >> '-001.456'
console.log(fillZeroes(-456.53453, 6)) // >> '-000456.53453'
console.log(fillZeroes('Agent 7', 3))  // >> 'Agent 007'
4
On

Unfortunately, there are a lot of needless complicated suggestions for this problem, typically involving writing your own function to do math or string manipulation or calling a third-party utility. However, there is a standard way of doing this in the base JavaScript library with just one line of code. It might be worth wrapping this one line of code in a function to avoid having to specify parameters that you never want to change like the local name or style.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumIntegerDigits: 3,
    useGrouping: false
});

This will produce the value of "005" for text. You can also use the toLocaleString function of Number to pad zeros to the right side of the decimal point.

var amount = 5;

var text = amount.toLocaleString('en-US',
{
    style: 'decimal',
    minimumFractionDigits: 2,
    useGrouping: false
});

This will produce the value of "5.00" for text. Change useGrouping to true to use comma separators for thousands.

Note that using toLocaleString() with locales and options arguments is standardized separately in ECMA-402, not in ECMAScript. As of today, some browsers only implement basic support, i.e. toLocaleString() may ignore any arguments.

Complete Example

0
On

ES6 makes this fairly trivial:

function pad (num, length, countSign = true) {
  num = num.toString()
  let negative = num.startsWith('-')
  let numLength = negative && !countSign ? num.length - 1 : num.length
  if (numLength >= length) {
    return num
  } else if (negative) {
    return '-' + '0'.repeat(length - numLength) + num.substr(1)
  } else {
    return '0'.repeat(length - numLength) + num
  }
}

pad(42, 4)          === '0042'
pad(12345, 4)       === '12345'
pad(-123, 4)        === '-100'
pad(-123, 4, false) === '-0100'
0
On

ECMAScript 2017: use padStart or padEnd

'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo");  // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"

More info:

0
On

If you use Lodash.

var n = 1;

alert( _.padLeft(n, 2, 0) ); // 01

n = 10;

alert( _.padLeft(n, 2, 0) ); // 10
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>

2
On

Not that this question needs more answers, but I thought I would add the simple lodash version of this.

_.padLeft(number, 6, '0')

0
On

I am using this simple approach

var input = 1000; //input any number
var len = input.toString().length;
for (i = 1; i < input; i++) {
  console.log("MyNumber_" + ('000000000000000' + i).slice(-len));
}
1
On

Just another solution, but I think it's more legible.

function zeroFill(text, size)
{
  while (text.length < size){
    text = "0" + text;
  }

  return text;
}

0
On

I really don't know why, but no one did it in the most obvious way. Here it's my implementation.

Function:

/** Pad a number with 0 on the left */
function zeroPad(number, digits) {
    var num = number+"";
    while(num.length < digits){
        num='0'+num;
    }
    return num;
}

Prototype:

Number.prototype.zeroPad=function(digits){
    var num=this+"";
    while(num.length < digits){
        num='0'+num;
    }
    return(num);
};

Very straightforward, I can't see any way how this can be any simpler. For some reason I've seem many times here on SO, people just try to avoid 'for' and 'while' loops at any cost. Using regex will probably cost way more cycles for such a trivial 8 digit padding.

0
On
function numPadding (padding,i) {
    return padding.substr(0, padding.length - (Math.floor(i).toString().length)) + Math.floor(i );
}

numPadding("000000000",234); -> "000000234"

or

function numPadding (number, paddingChar,i) {
    var padding = new Array(number + 1).join(paddingChar);
    return padding.substr(0, padding.length - (Math.floor(i).toString().length)) + Math.floor(i );
}

numPadding(8 ,"0", 234); -> "00000234";
2
On

I used

Utilities.formatString("%04d", iThe_TWO_to_FOUR_DIGIT) 

which gives up to 4 leading 0s

NOTE: THIS REQUIRES Google's apps-script Utilities:

https://developers.google.com/apps-script/reference/utilities/utilities#formatstringtemplate-args

0
On

Just an FYI, clearer, more readable syntax IMHO

"use strict";
String.prototype.pad = function( len, c, left ) {
    var s = '',
        c = ( c || ' ' ),
        len = Math.max( len, 0 ) - this.length,
        left = ( left || false );
    while( s.length < len ) { s += c };
    return ( left ? ( s + this ) : ( this + s ) );
}
Number.prototype.pad = function( len, c, left ) {
    return String( this ).pad( len, c, left );
}
Number.prototype.lZpad = function( len ) {
    return this.pad( len, '0', true );
}

This also results in less visual and readability glitches of the results than some of the other solutions, which enforce '0' as a character; answering my questions what do I do if I want to pad other characters, or on the other direction (right padding), whilst remaining easy to type, and clear to read. Pretty sure it's also the DRY'est example, with the least code for the actual leading-zero-padding function body (as the other dependent functions are largely irrelevant to the question).

The code is available for comment via gist from this github user (original source of the code) https://gist.github.com/Lewiscowles1986/86ed44f428a376eaa67f

A note on console & script testing, numeric literals seem to need parenthesis, or a variable in order to call methods, so 2.pad(...) will cause an error, whilst (2).pad(0,'#') will not. This is the same for all numbers it seems

0
On

I just stumbled upon this post looking for a native solution. Since there isn't a built-in solution, here's my take on it:

function zerofill(number, width) {
    var num = '';
    while (width-- > 0) {
        num += '0';
    }

    return num.slice(0, - (number + '').length) + number + '';
}
0
On

A simple function to do it:

function padStr(number, numDigits){
  return 
    (number < 0 ? '-':'') 
    + ((new Array(numDigits + 1).join("0"))
    + Math.abs(number)).slice(-numDigits);
}
0
On

A simple short recursive function to achieve your proposal:

function padleft (YourNumber, OutputLength){
    if (YourNumber.length >= OutputLength) {
        return YourNumber;
    } else {
        return padleft("0" +YourNumber, OutputLength);
    }
}
  • YourNumber is the input number.
  • OutputLength is the preferred output number length (with 0 padding left).

This function will add 0 on the left if your input number length is shorter than the wanted output number length.

0
On

In all modern browsers you can use

numberStr.padStart(numberLength, "0");

function zeroFill(num, numLength) {
  var numberStr = num.toString();

  return numberStr.padStart(numLength, "0");
}

var numbers = [0, 1, 12, 123, 1234, 12345];

numbers.forEach(
  function(num) {
    var numString = num.toString();
    
    var paddedNum = zeroFill(numString, 5);

    console.log(paddedNum);
  }
);

Here is the MDN reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

1
On

Here's a little trick I think is cool:

(2/10000).toString().split(".")[1]
"0002"
(52/10000).toString().split(".")[1]
"0052"
2
On

Mnah... I have not seen a "ultimate" answer to this issue and if you are facing the same challenge I must save you some time by saying that sadly there's not built-in function for that on JavaScript.

But there's this awesome function in PHP that does a great job on padding strings as well as numbers with single character or arbitrary strings. After some time of banging my head for not having the right tool on JavaScript (mostly for zerofillin' numbers and usually for trimming strings to fit a fixed length) and excessive coding work, I decided to write my own function.

It does the same ("almost the same"; read on for detail) that the dream PHP function does, but in comfortable client-side JavaScript:

function str_pad(input, pad_length, pad_string, pad_type) {
    var input = input.toString();
    var output = "";

    if((input.length > pad_length) &&
       (pad_type == 'STR_PAD_RIGHT')) {

        var output = input.slice(0, pad_length);
    }
    else
        if((input.length > pad_length) &&
           (pad_type == 'STR_PAD_LEFT')) {

            var output = input.slice(input.length -
                                     pad_length,input.length);
        }
        else
            if((input.length < pad_length) &&
               (pad_type == 'STR_PAD_RIGHT')) {

                var caracteresNecesarios = pad_length-input.length;
                var rellenoEnteros = Math.floor(caracteresNecesarios/pad_string.length);
                var rellenoParte = caracteresNecesarios%pad_string.length;
                var output = input;
                for(var i=0; i<rellenoEnteros; i++) {
                    var output = output + pad_string;
                };
                var output = output + pad_string.slice(0, rellenoParte);
            }
            else
                if((input.length < pad_length) &&
                   (pad_type=='STR_PAD_LEFT')) {

                    var caracteresNecesarios = pad_length-input.length;
                    var rellenoEnteros = Math.floor(caracteresNecesarios/pad_string.length);
                    var rellenoParte = caracteresNecesarios%pad_string.length;
                    var output = "";
                    for(var i=0; i<rellenoEnteros; i++) {
                        var output = output + pad_string;
                    };
                    var output = output + pad_string.slice(0, rellenoParte);
                    var output = output + input;
                }
                else
                    if(input.length == pad_length) {
                        var output = input;
                    };
    return output;
};

The only thing that my function does not do is the STR_PAD_BOTH behavior that I could add with some time and a more comfortable keyboard. You might call the function and test it; bet you'll love it if you don't mind that inner code uses one or two words in Spanish... not big deal I think. I did not added comments for "watermarking" my coding so you can seamless use it in your work nor I compressed the code for enhanced readability. Use it and test it like this and spread the code:

alert("str_pad('murcielago', 20, '123', 'STR_PAD_RIGHT')=" + str_pad('murcielago', 20, '123', 'STR_PAD_RIGHT') + '.');
0
On
function numberPadding(n, p) {
  n = n.toString();
  var len = p - n.length;
  if (len > 0) {
    for (var i=0; i < len; i++) {
      n = '0' + n;
    }
  }
  return n;
}
0
On

My solution

Number.prototype.PadLeft = function (length, digit) {
    var str = '' + this;
    while (str.length < length) {
        str = (digit || '0') + str;
    }
    return str;
};

Usage

var a = 567.25;
a.PadLeft(10); // 0000567.25

var b = 567.25;
b.PadLeft(20, '2'); // 22222222222222567.25
1
On

If performance is really critical (looping over millions of records), an array of padding strings can be pre-generated, avoiding to do it for each call.

Time complexity: O(1).
Space complexity: O(1).

const zeroPads = Array.from({ length: 10 }, (_, v) => '0'.repeat(v))

function zeroPad(num, len) {
  const numStr = String(num)
  return (zeroPads[len - numStr.length] + numStr)
}

0
On

I came up with an absurd one-liner while writing a numeric base converter.

// This is cursed
function p(i,w,z){z=z||0;w=w||8;i+='';var o=i.length%w;return o?[...Array(w-o).fill(z),...i].join(''):i;}

console.log(p(8675309));        // Default: pad w/ 0 to 8 digits
console.log(p(525600, 10));     // Pad to 10 digits
console.log(p(69420, 10, 'X')); // Pad w/ X to 10 digits
console.log(p(8675309, 4));     // Pad to next 4 digits
console.log(p(12345678));       // Don't pad if you ain't gotta pad

Or, in a form that doesn't quite as readily betray that I've sold my soul to the Black Perl:

function pad(input, width, zero) {
    zero = zero || 0; width = width || 8;  // Defaults
    input += '';                           // Convert input to string first

    var overflow = input.length % width    // Do we overflow?
    if (overflow) {                        // Yep!  Let's pad it...
        var needed = width - overflow;     // ...to the next boundary...
        var zeroes = Array(needed);        // ...with an array...
        zeroes = zeroes.fill(zero);        // ...full of our zero character...
        var output = [...zeroes,...input]; // ...and concat those zeroes to input...
        output = output.join('');          // ...and finally stringify.
    } else {
        var output = input;                // We don't overflow; no action needed :)
    }

    return output;                         // Done!
}

One thing that sets this apart from the other answers is that it takes a modulo of the number's length to the target width rather than a simple greater-than check. This is handy if you want to make sure the resulting length is some multiple of a target width (e.g., you need the output to be either 5 or 10 characters long).

I have no idea how well it performs, but hey, at least it's already minified!

0
On

Modern browsers now support padStart, you can simply now do:

string.padStart(maxLength, "0");

Example:

string = "14";
maxLength = 5; // maxLength is the max string length, not max # of fills
res = string.padStart(maxLength, "0");
console.log(res); // prints "00014"

number = 14;
maxLength = 5; // maxLength is the max string length, not max # of fills
res = number.toString().padStart(maxLength, "0");
console.log(res); // prints "00014"

0
On

I think my approach is a little different. The reason I needed to pad a number was to display it in a <pre> element (part of an on-screen log), so it's ultimately going to be a string anyway. Instead of doing any math, I wrote a simple function to overlay a string value on a mask string:

function overlayr(m, s) {
  return m.length > s.length ? m.substr(0, m.length - s.length) + s : s;
}

The benefit of this is that I can use it for all sorts of string alignment tasks. To call it, just pass in the mask and number as a string:

> overlayr('00000', (5).toString())
< "00005"

As an added bonus, it deals with overflows correctly:

> overlayr('00000', (555555).toString())
< "555555"

And of course it's not limited to 0 padding:

> overlayr('*****', (55).toString())
< "***55"
0
On

This is an angular provider that I wrote, which makes use of @profitehlolz 's answer but employs memoization so that commonly used pad length-pad character combinations will not invoke the array build join needlessly:

angular.module('stringUtilities', [])
    .service('stringFunctions', [function() {
        this.padMemo={ };
        this.padLeft=function(inputString,padSize,padCharacter) {

            var memoKey=padSize+""+padCharacter;

            if(!this.padMemo[memoKey]) {

                this.padMemo[memoKey]= new Array(1 + padSize).join(padCharacter);
            }

           var pad=this.padMemo[memoKey];
           return (pad + inputString).slice(-pad.length);
       };
}]);
0
On

Yet another version :

function zPad(s,n){
    return (new Array(n+1).join('0')+s).substr(-Math.max(n,s.toString().length));
}
1
On

The power of Math!

x = integer to pad
y = number of zeroes to pad

function zeroPad(x, y)
{
   y = Math.max(y-1,0);
   var n = (x / Math.pow(10,y)).toFixed(y);
   return n.replace('.','');  
}
1
On

A simple elegant solution, where n is the number and l is the length.

function nFill (n, l) {return (l>n.toString().length)?((Array(l).join('0')+n).slice(-l)):n;}

This keeps the length if it is over desired, as not to alter the number.

n = 500;

console.log(nFill(n, 5));
console.log(nFill(n, 2));

function nFill (n, l) {return (l>n.toString().length)?((Array(l).join('0')+n).slice(-l)):n;}

0
On

I was here looking for a standard and had the same idea as Paul and Jonathan... Theirs are super cute, but here's a horrible-cute version:

function zeroPad(n, l, i) {
    return (i = n/Math.pow(10, l))*i > 1 ? '' + n : i.toFixed(l).replace('0.', '');
}

This works too (we're assuming integers, yes?)...

> zeroPad(Math.pow(2, 53), 20);
'00009007199254740992'

> zeroPad(-Math.pow(2, 53), 20);
'-00009007199254740992'

> zeroPad(Math.pow(2, 53), 10);
'9007199254740992'

> zeroPad(-Math.pow(2, 53), 10);
'-9007199254740992'
8
On

Simple way. You could add string multiplication for the pad and turn it into a function.

var pad = "000000";
var n = '5';
var result = (pad+n).slice(-pad.length);

As a function,

function paddy(num, padlen, padchar) {
    var pad_char = typeof padchar !== 'undefined' ? padchar : '0';
    var pad = new Array(1 + padlen).join(pad_char);
    return (pad + num).slice(-pad.length);
}
var fu = paddy(14, 5); // 00014
var bar = paddy(2, 4, '#'); // ###2