Reputation: 48983
Using JavaScript is there a way to take a Date string like this 9/17/2014
and modify it so that the day and month values are always padded with a 0 if they are single digit in length?
The catch is that the delimiter /
can be anything. Generally it would be -
or /
so if it only looked for those 2 would be fine to.
Also the order of the day, month, and year can be in any position.
My end goal is to take a date string and make it so that the Date portion is always 10 characters in length so that I can then grab the remaining characters is they exist and always assume they are the Time portion of the DateTime string.
If I get a string like this though 9/17/2014
then the Date portion is only 9 long and if the day was single digit like 9/7/2014
then it would only be 8 long.
I am working on this JavaScript function to convert a Date string into a JS Date object. It allows any style delimiter and any order for the day, month, and year parts.
My goal is to modify it to also allow Date strings that can have a Time after the Date part and parse them into time pieces.
If the string has the Time parts, I will assume time delimiter will always be :
.
The separator between the Date and a Time in the string could be either:
04/04/2016 12:23:12
T
like 04/04/2016T12:23:12
Also the time may or may not have the ending am
or pm
.
My issue at the moment is the Date part sometimes not being the 10 character length so if I could auto 0 pad single digit day and months it might help in the end goal.
Any help with any of this goal appreciated though, thanks
// Convert Date String into JS Date Object
// Can parse multiple Date formats
// stringToDate("17/9/2014", "dd/MM/yyyy", "/");
// stringToDate("9/17/2014", "mm/dd/yyyy", "/");
// stringToDate("9-17-2014", "mm-dd-yyyy", "-");
stringToDate: function(d, _format, _delimiter) {
if((d instanceof Date)){
return d;
}
if(d.length > 10){
// it might have a Time string at the end
var dateString = d.substring(0, 10);
console.log(dateString);
}
var formatLowerCase = _format.toLowerCase();
var formatItems = formatLowerCase.split(_delimiter);
var dateItems = d.split(_delimiter);
var monthIndex = formatItems.indexOf("mm");
var dayIndex = formatItems.indexOf("dd");
var yearIndex = formatItems.indexOf("yyyy");
var month = parseInt(dateItems[monthIndex]);
month -= 1;
var formatedDate = new Date(dateItems[yearIndex], month, dateItems[dayIndex]);
return formatedDate;
},
Upvotes: 1
Views: 1680
Reputation: 48070
This kind of replacing isn't as elegant as it can be with regex engines that fully support lookbehinds. Nonetheless, this is a single-step technique to add zeros to single-digit values in dates and datetime expressions.
Effectively, you seek out a string that either starts with a single-digit before a non-digit OR a non-digit that is immediately followed by a single-digit then either a colon, a slash, a hyphen, or the end of the string.
I am only using a capture group because js doesn't seem to appreciate it when I use $00
. $10
means: write the first captured string (in this case, either an empty string or a non-digit), then add a zero.
let dates = [
'17/9/2014',
'9/17/2015',
'9-17-2016',
'4/4/2017 2:2:2',
'5-5-2018 12:2:59',
'6/6/2019 2:59:59',
'7-17-2020T1:2:3',
];
for (let i in dates) {
document.write('<div>' + dates[i].replace(/(^(?=\d\D)|\D(?=\d(?:[:/-]|$)))/g, '$10') + '</div>');
}
Upvotes: 0
Reputation: 65
please note that when padding, the number could be a string or a number, so this needs to be checked first to get the correct result
pad(n){
if(typeof n.length != 'undefined'){ // string
return (n.length == 1) ? "0"+n : n;
}
else { // number
if (n < 10) {
return "0" + n;
}
return n;
}
}
Upvotes: 0
Reputation: 147523
Just adding this as here are a couple of answers that seem quite verbose.
I usually add the following function within the date formatting function. It can be concise because you know that you only need to deal with positive integers and only need to pad numbers 0 to 9 inclusive.
function z(n){return (n<10? '0':'') + n}
Then use it like:
z(date.getMonth()+1)
An alternative is:
function z(n){return ('0'+n).slice(-1)}
However, I think your strategy of reformatting the string and then parsing it isn't efficient, just parse it.
Upvotes: 0
Reputation: 15462
A couple of suggestions - if appropriate for your situation use moments.js.
Often times I just use a set of regular expressions. The sample below does that and just attaches any remainder for use as a date string.:
function cleanDate(d){ // strips leading 0s from php date and converts dashes to slashes
function pad(v){ if(parseInt(v,10) >= 10) return v; return "0"+v;}
var dM = /0?(\d{1,2})[-\/]0?(\d+)[-\/](\d{4})(.*)/.exec(d); //assume month/date/year
if(dM) return pad(dM[1]) +'/'+ pad(dM[2]) +'/'+ dM[3]+dM[4];
dM = /(\d{4})[-\/]0?(\d+)[-\/]0?(\d+)(.*)/.exec(d); //assume year-month-date
if(dM) return pad(dM[2]) +'/'+ pad(dM[3]) +'/'+ dM[1]+dM[4];
return d;// cannot do anything with it
}
Upvotes: 1
Reputation: 63587
You can use an iterating function to pad out the date:
function pad(str) {
if (str.length === 2) return str;
return pad('0' + str);
}
And use a mediating function to separate the date components and pad them where necessary:
function padDate(str, delimiter) {
return str.split(delimiter).map(function (el) {
if (el.length < 2) return pad(el);
return el;
}).join(delimiter);
}
Declare what you want the delimiter to be as a parameter to the padDate
function.
padDate('9/17/2014', '/'); // 09/17/2014
padDate('19-7-2014', '-'); // 19-07-2014
Upvotes: 1