Javascript add leading zeroes to date

474,982

Solution 1

Try this: http://jsfiddle.net/xA5B7/

var MyDate = new Date();
var MyDateString;

MyDate.setDate(MyDate.getDate() + 20);

MyDateString = ('0' + MyDate.getDate()).slice(-2) + '/'
             + ('0' + (MyDate.getMonth()+1)).slice(-2) + '/'
             + MyDate.getFullYear();

EDIT:

To explain, .slice(-2) gives us the last two characters of the string.

So no matter what, we can add "0" to the day or month, and just ask for the last two since those are always the two we want.

So if the MyDate.getMonth() returns 9, it will be:

("0" + "9") // Giving us "09"

so adding .slice(-2) on that gives us the last two characters which is:

("0" + "9").slice(-2)
"09"

But if MyDate.getMonth() returns 10, it will be:

("0" + "10") // Giving us "010"

so adding .slice(-2) gives us the last two characters, or:

("0" + "10").slice(-2)
"10"

Solution 2

The modern way

The new modern way to do this is to use toLocaleDateString, because it allows you not only to format a date with proper localization, but even to pass format options to achieve the desired result:

const date = new Date(2018, 2, 1)
const result = date.toLocaleDateString("en-GB", { // you can use undefined as first argument
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
})
console.log(result) // outputs “01/03/2018”

Or using a Temporal object (still in proposal, caniuse):

const date = new Temporal.PlainDate(2018, 3, 1) // also works with zoned date
const result = date.toLocaleString("en-GB", { // you can use undefined as first argument
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
})
console.log(result) // outputs “01/03/2018”

When you use undefined as the first argument it will detect the browser language, instead. Alternatively, you can use 2-digit on the year option, too.

Performance

If you plan to format a lot of dates, you should consider using Intl.DateTimeFormat instead:

const formatter = new Intl.DateTimeFormat("en-GB", { // <- re-use me
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
})
const date = new Date(2018, 2, 1) // can also be a Temporal object
const result = formatter.format(date)
console.log(result) // outputs “01/03/2018”

The formatter is compatible with Date and Temporal objects.

Historical dates

Unlike in the Temporal constructor years between 0 and 99 will be interpreted as 20th century years on the Date constructor. To prevent this, initialize the date like so:

const date = new Date()
date.setFullYear(18, 2, 1) // the year is A.D. 18

This is not required for Temporal objects, but years below 1000 will not contain leading zeros in all cases, because the formatter (that is shared for the Date and Temporal API) does not support 4-digit formatting at all. In this case you have to do manual formatting (see below).

For the ISO 8601 format

If you want to get your date in the YYYY-MM-DD format (ISO 8601), the solution looks different:

const date = new Date(Date.UTC(2018, 2, 1))
const result = date.toISOString().split('T')[0]
console.log(result) // outputs “2018-03-01”

Your input date should be in the UTC format or toISOString() will fix that for you. This is done by using Date.UTC as shown above.

Historical dates for the ISO 8601 format

Unlike in the Temporal constructor years between 0 and 99 will be interpreted as 20th century years on the Date constructor. To prevent this, initialize the date like so to be used for the ISO 8601 format:

const date = new Date()
date.setUTCFullYear(18, 2, 1) // the year is A.D. 18

Note that the ISO format for Temporal objects with dates before the year 1000 or after the year 9999 will have a different formatting compared to the legacy Date API. It is recommend to fallback to custom formatting to enforce 4 digit years in all circumstances.

Custom 4-digit formatting on the year

Sadly, the formatter doesn't support leading zeros on the year. There is no 4-digit option. This will remain for Temporal objects as well, because they do share the same formatter.

Fortunately, the ISO format of the Date API will always display at least 4 digits on the year, although Temporal objects do not. So at least for the Date API you can format historical dates before the year 1000 with leading zeros by falling back to a manual formatting approach using part of the ISO 8601 format method:

const date = new Date()
date.setUTCFullYear(18, 2, 1)
const ymd = date.toISOString().split('T')[0].split('-')
const result = `${ymd[2]}/${ymd[1]}/${ymd[0]}`
console.log(result) // outputs “01/03/0018”

For a Temporal object a different route is necessary, since the ISOYearString will be formatted differently for dates before the year 1000 and after the year 9999 as mentioned before:

const date = new Temporal.PlainDate(2018, 3, 1) // also works with zoned date
const zeroPad = (n, digits) => n.toString().padStart(digits, '0');
const result = `${zeroPad(date.day, 2)}/${zeroPad(date.month, 2)}/${zeroPad(date.year, 4)}`;
console.log(result) // outputs “01/03/0018”

Miscellaneous

For the Date and Temporal API there is also toLocaleTimeString, that allows you to localize and format the time of a date.

Solution 3

Here is an example from the Date object docs on the Mozilla Developer Network using a custom "pad" function, without having to extend Javascript's Number prototype. The handy function they give as an example is

function pad(n){return n<10 ? '0'+n : n}

And below is it being used in context.

/* use a function for the exact format desired... */
function ISODateString(d){
    function pad(n){return n<10 ? '0'+n : n}
    return d.getUTCFullYear()+'-'
    + pad(d.getUTCMonth()+1)+'-'
    + pad(d.getUTCDate())+'T'
    + pad(d.getUTCHours())+':'
    + pad(d.getUTCMinutes())+':'
    + pad(d.getUTCSeconds())+'Z'
}

var d = new Date();
console.log(ISODateString(d)); // prints something like 2009-09-28T19:03:12Z

Solution 4

For you people from the future (ECMAScript 2017 and beyond)

Solution

"use strict"

const today = new Date()

const year = today.getFullYear()

const month = `${today.getMonth() + 1}`.padStart(2, "0")

const day = `${today.getDate()}`.padStart(2, "0")

const stringDate = [day, month, year].join("/") // 13/12/2017

Explaination

the String.prototype.padStart(targetLength[, padString]) adds as many as possible padString in the String.prototype target so that the new length of the target is targetLength.

Example

"use strict"

let month = "9"

month = month.padStart(2, "0") // "09"

let byte = "00000100"

byte = byte.padStart(8, "0") // "00000100"

Solution 5

You can define a "str_pad" function (as in php):

function str_pad(n) {
    return String("00" + n).slice(-2);
}
Share:
474,982
Julian Coates
Author by

Julian Coates

Updated on February 21, 2022

Comments

  • Julian Coates
    Julian Coates about 2 years

    I've created this script to calculate the date for 10 days in advance in the format of dd/mm/yyyy:

    var MyDate = new Date();
    var MyDateString = new Date();
    MyDate.setDate(MyDate.getDate()+10);
    MyDateString = MyDate.getDate() + '/' + (MyDate.getMonth()+1) + '/' + MyDate.getFullYear();
    

    I need to have the date appear with leading zeroes on the day and month component by way of adding these rules to the script. I can't seem to get it to work.

    if (MyDate.getMonth < 10)getMonth = '0' + getMonth;
    

    and

    if (MyDate.getDate <10)get.Date = '0' + getDate;
    

    If someone could show me where to insert these into the script I would be really appreciative.

  • tomexx
    tomexx over 11 years
    Forked - date format YYYY-MM-DD jsfiddle.net/j6qJp/1 It may be useful for somebody. Thanks
  • claudio
    claudio over 10 years
    Can someone explain why this is better than the answer that @Aleross provides below? It is not immediately clear what it does versus the pad function which is explicitly clear.
  • John Henckel
    John Henckel about 10 years
    Simpler, just use myDate.toISOString() which has leading zeros. Parse out relevant parts using substring.
  • PhistucK
    PhistucK about 10 years
    @n00b I agree. This is longer and seems like an overkill. Also, it looks worse in terms of performance (calling slice following a concatenation looks more expensive than a simple string concatenation following a comparison), but I am not a computer science graduate or anything like that. It is a creative solution, indeed, but nothing more than that, I think.
  • rickb
    rickb about 10 years
    Way clever. Works fine for short, quick strings. Probably want to do something more performant if you were processing a lot of them. In a dragging display scenario, dragging and formatting across several date/time ticks and displaying them on the fly in a moving window - works just fine.
  • DazManCat
    DazManCat almost 10 years
    Not to mention that today this example gave me 26/06/2014 instead of 06/06/2014
  • cookie monster
    cookie monster almost 10 years
    @DazManCat: That's what it is supposed to do. The code starts by adding 20 days to the current date. MyDate.setDate(MyDate.getDate() + 20);
  • Phil Cooper
    Phil Cooper over 9 years
    @n00b I suppose it's not necessarily better, just more popular. I'm guessing if they are put side-by-side, it would be because of the additional private function required to perform the pad.
  • Karl
    Karl over 8 years
    @n00b and @Phil Cooper, without getting hung up on a discussion about the ins and outs of timing JavaScript routines, I found that the slice() technique in the accepted answer is about a 1/10 of a second faster than @Aleross 's pad() technique on 1 million iterations. jsFiddle. "pay your money, take your pick".
  • Binke
    Binke over 8 years
    Very nice way of doing it. I think the accepted answer is really nice, but this even cleaner in my opinion
  • David Fregoli
    David Fregoli almost 7 years
    "0" instead of "00" is enough
  • David Fregoli
    David Fregoli almost 7 years
    this could lead to unexpected bugs cause it outputs a string for < 10 and a number for >= 10
  • Rohmer
    Rohmer over 6 years
    @DavidFregoli, all those date to string functions return a string, so if you input a string, pad does output only strings.
  • mplungjan
    mplungjan over 6 years
    function pad(num) { return ("0"+num).slice(-2);}
  • Noel Llevares
    Noel Llevares over 6 years
    This is part of ES2017 or ES8. So it's incorrect to say "ES6+" as it's not part of ES6 and ES7.
  • JoseLinares
    JoseLinares almost 6 years
    This is exactly what I was looking for, thanks. More info about the options available for toLocaleDateString here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • Max Alexander Hanna
    Max Alexander Hanna over 5 years
    liked this the most : myDate.getDate().toLocaleString('en-US', {minimumIntegerDigits: 2})
  • Martin Braun
    Martin Braun about 5 years
    @JoseLinares Hi, thanks for putting this link back in the days. I just decided to improve my answer to make the solution more appealing for common scenarios, since you can skip the first argument and IE10 is not relevant anymore. With that in mind, I included your link into my answer.
  • Shiv Kumar Baghel
    Shiv Kumar Baghel almost 5 years
    you can also describe in short what you attempt.
  • Tomas Gonzalez
    Tomas Gonzalez almost 5 years
    @claudio because there's no need to declare a function.
  • Kanhaiya lal
    Kanhaiya lal almost 5 years
    @modiX, sorry it was a my mistake in code and i took wrong way the description, Yes the locales (first variable) is Optional.
  • Gobliins
    Gobliins over 4 years
    I like this solution, can you maybe clarifiy a bit what happens there?
  • Basil Bourque
    Basil Bourque over 4 years
    Take care in spelling "JavaScript".
  • leopal
    leopal over 4 years
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.
  • bmaupin
    bmaupin about 4 years
    This should technically be .padStart(2, '0') since the second parameter is a string, although it probably won't matter unless you're using TypeScript
  • SeaWarrior404
    SeaWarrior404 over 3 years
    Could you please explain how this works? Seems like an elegant solution
  • Povesma Dmytro
    Povesma Dmytro over 3 years
    Regexp finds maximum of three groups: $1 - any non-digit symbol (or beginning of the line) $2 - any digit $3 - any non-digit (that may not exist) Then we're replacing the captured (matched) stuff with $1 + "0" + $2 which comes $10$2 in the replacement string.
  • Povesma Dmytro
    Povesma Dmytro over 3 years
    It finds a single digit (between any other symbols) and adds a zero before this single digit You can play with S = ['1/2/16', '2.10.20', '3 5 9', 'Today is 4.5.20', 'US style 3/9/21']; S.forEach(s => console.log(s.replace(/(^|\D)(\d)(?!\d)/g, '$10$2')))
  • Baccata
    Baccata almost 3 years
    And you missed the +1 for the month
  • Chupo_cro
    Chupo_cro almost 3 years
    $3 does not exist in your regex, (?!\d) is negative lookahead not to add the leading zero if there is more than one digit.
  • Tim
    Tim over 2 years
    Thank you! Clean and exactly what I needed!
  • Sixteen
    Sixteen over 2 years
    How to add leading zeros to the year using this method ? year: "numeric" displays the year as is, not on 4 digits :(
  • Sixteen
    Sixteen over 2 years
    This solution is really elegant.
  • Martin Braun
    Martin Braun over 2 years
    @Sixteen Unfortunately, there is no 4-digit format option to address historical dates below the year 1000 with the modern approach. I updated my answer to address your issue and provide an alternative solution for this case. I wish there was a better way to do this, though.
  • Kulgar
    Kulgar almost 2 years
    What a clever solution, thank you!