Javascript: Mutating "05/01/2013" into "20130501"? - javascript

So I have a string that represents a date and I need to change the format of it. This is what I have so far:
function myFunction()
{
var dateto = "05/01/2013";
dateto.replace("/", "");
//now what?
}
It will always originally be in the MM/DD/YYYY format, and I need to change it to a YYYYMMDD format. I'm looking for something on the lines of dateto = dateto[5..8] + dateto[0..1] + dateto[2..3]
. Not sure how to write that in JS though.

You can use some simple string maniuplation
var dateto = "05/01/2013";
var parts = dateto.split('/');
var newDate = parts[2] + parts[0] + parts[1];
Fiddle: http://jsfiddle.net/kvU6H/

This can be done using replace with a regular expression and capture groups:
"05/01/2013".replace(
/(\d{2})\/(\d{2})\/(\d{4})/, // capture data in groups
"$3$1$2") // replace with captured groups
While the above approach works well enough for this specific case, consider a library like moment.js:
moment
.parse("05/01/2013", "MM/DD/YYY") // parse our format
.format("YYYYMMDD") // write target format

You could consider the substring() function where you just provide the beginning and end positions (or indexes) of the desired string in the original string:
function myFunction()
{
var dateto = "05/01/2013";
return dateto.substring(6, 10) + dateto.substring(0, 2) + dateto.substring(3, 5);
}
returns:
20130501
Indexes start from 0 in Javascript (and most programming languages)... so for your string:
string: 0 5 / 0 1 / 2 0 1 3
index: 0 1 2 3 4 5 6 7 8 9

Related

javascript format date from DDMMYYYY to DD/MM/YYYY

I have a datepicker and I want to parse the date to dd/mm/yyyy when user input is ddmmyyyy.
Image
I have add a javascript function to the input text but I don't know if I am on the right way
<inputText id="input1" onchange="parseDate()"/>
<script type="text/javascript">
$(document).ready(function() {
$("#input1").datepicker()
};
function parseDate() {
???
}
<script>
Thanks
If that's the exact format you're looking at, then you could just parse it out:
http://jsfiddle.net/q3yrtu0z/
$('#input1').change(function() {
$(this).val($(this).val().replace(/^(\d{2})(\d{2})(\d{4})$/, '$1/$2/$3'));
});
This is designed such that if the value is exactly 8 digits, then it will format it XX/XX/XXXX.
You may want to do additional validation on the validity of the date format (although you'd have to do this for MM/DD/YYYY inputs as well anyway)
Try this....
function convertDate(inputFormat) {function pad(s) { return (s < 10) ? '0' + s : s; } var d = new Date(inputFormat); return [pad(d.getDate()), pad(d.getMonth()+1), d.getFullYear()].join('/'); }
As you're going for a simple transformation, consider sliceing your String to the points where you want to add your characters, for example
var strA = '13102015',
strB = strA.slice(0, 2) + '/' + strA.slice(2, 4) + '/' + strA.slice(4);
strB; // "13/10/2015"
As this may be invoked multiple times if the user modifies it later, you may also wish to force the input into expected formatting at the start using replace, e.g.
'13/102015'.replace(/[^\d]/g, ''); // "13102015"
// now continue to slice
In a RegExp,
[chars] means match these characters (in this case c, h, a, r, s)
[^chars] is the inverse of [chars], i.e. match any character except these characters
\d is any digit, i.e. the numbers 0 to 9
The g flag means global, i.e. after a match keep looking for another match

2 or 4 Digit Date Validation with Javascript String Replacement

EDIT: To anyone making the same mistake I did in asking this question, please look for my amended answer below which demonstrates a MUCH cleaner solution to this problem.
Trying to permit user entry of either 2 digit or 4 digit date format and allow both to pass validation but autocorrect the 2 digit format with the 4 digit equivalent with the assumption that the leading 2 digits should be the same as the current leading 2 digits.
I'm having trouble with the javascript replace() function. This line:
input.replace(enteredDate, year);
is not working as expected. In the context of the spine.js framework I'm using, the input refers to $(event.target) and appears to be correct everywhere else in manipulating the input field where the validation should be occurring. Ultimately, I want to replace the original string found in the input field with the fully concatenated one (which I haven't built out yet), but for now, how can I replace the contents of input (where input is var = $(event.target)) with the var year assigned here:
var year = currentYear.charAt(0) + currentYear.charAt(1) + unparsedYear;
Here is the full code for the function I have so far, which is throwing the following error in reference to the .replace() line - Uncaught TypeError: Object [object Object] has no method 'replace'
validateDate: function(event) {
var input = $(event.target);
var enteredDate = input.val();
input.destroyValidationMessage();
var pattern = /^(\d{1,2})\/(\d{1,2})\/(\d{2})|(\d{4})$/;
var result = enteredDate.match(pattern);
if (result !== null) {
var month = parseInt(result[1], 10);
var day = parseInt(result[2], 10);
var year = parseInt(result[3], 10);
var unparsedYear = parseInt(result[3], 10);
var unparsedYearStrLength = unparsedYear.toString().length;
if ( unparsedYearStrLength < 4) {
var currentYear = new Date().getFullYear().toString();
var year = currentYear.charAt(0) + currentYear.charAt(1) + unparsedYear;
alert('Autocorrected year will be ' + year);
input.replace(enteredDate, year);
}
var date = new Date(year, month - 1, day);
var isValid = date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
} else {
input.createValidationMessage('Invalid Date');
input.addClass('invalid');
}
}
As mentioned in my comment above:
input is a DOM element, but you actually want to replace the content of the element vs. the element itself, so use input.val(new_value) and not the actual input element.

Javascript date regex DD/MM/YYYY

I know there are a lot of regex threads out there by I need a specific pattern I couldn't fin anywhere
This regex validates in a YYYY-MM-DD format
/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/
I need the pattern to be DD/MM/YYYY
(day first since it's in spanish and only "/", "-" should not be allowed)
I searched several regex libraries and I think this one should work... but since I'm not familiar with regex I'm not sure it validates like that
(0[1-9]|[12][0-9]|3[01])[ \.-](0[1-9]|1[012])[ \.-](19|20|)\d\d
I also don't know ho to escape the slashes, I try to "see" the logic in the string but it's like trying "see" the Matrix code for me. I'm placing the regex string in a options .js
[...] },
"date": {
"regex": (0[1-9]|[12][0-9]|3[01])[ \.-](0[1-9]|1[012])[ \.-](19|20|)\d\d,
"alertText": "Alert text AAAA-MM-DD"
},
"other type..."[...]
So, if the regex is ok, how would I escape it?
if it's not, what's the correct regex and how do I escape it? :P
Thanks a lot
You could take the regex that validates YYYY/MM/DD and flip it around to get what you need for DD/MM/YYYY:
/^(0?[1-9]|[12][0-9]|3[01])[\/\-](0?[1-9]|1[012])[\/\-]\d{4}$/
BTW - this regex validates for either DD/MM/YYYY or DD-MM-YYYY
P.S. This will allow dates such as 31/02/4899
A regex is good for matching the general format but I think you should move parsing to the Date class, e.g.:
function parseDate(str) {
var m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/);
return (m) ? new Date(m[3], m[2]-1, m[1]) : null;
}
Now you can use this function to check for valid dates; however, if you need to actually validate without rolling (e.g. "31/2/2010" doesn't automatically roll to "3/3/2010") then you've got another problem.
[Edit] If you also want to validate without rolling then you could add a check to compare against the original string to make sure it is the same date:
function parseDate(str) {
var m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/)
, d = (m) ? new Date(m[3], m[2]-1, m[1]) : null
, nonRolling = (d&&(str==[d.getDate(),d.getMonth()+1,d.getFullYear()].join('/')));
return (nonRolling) ? d : null;
}
[Edit2] If you want to match against zero-padded dates (e.g. "08/08/2013") then you could do something like this:
function parseDate(str) {
function pad(x){return (((''+x).length==2) ? '' : '0') + x; }
var m = str.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})$/)
, d = (m) ? new Date(m[3], m[2]-1, m[1]) : null
, matchesPadded = (d&&(str==[pad(d.getDate()),pad(d.getMonth()+1),d.getFullYear()].join('/')))
, matchesNonPadded = (d&&(str==[d.getDate(),d.getMonth()+1,d.getFullYear()].join('/')));
return (matchesPadded || matchesNonPadded) ? d : null;
}
However, it will still fail for inconsistently padded dates (e.g. "8/08/2013").
Take a look from here https://www.regextester.com/?fam=114662
Use this following Regular Expression Details, This will support leap year also.
var reg = /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|(([1][26]|[2468][048]|[3579][26])00))))$/g;
Example
Scape slashes is simply use \ before / and it will be escaped. (\/=> /).
Otherwise you're regex DD/MM/YYYY could be next:
/^[0-9]{2}[\/]{1}[0-9]{2}[\/]{1}[0-9]{4}$/g
Explanation:
[0-9]: Just Numbers
{2} or {4}: Length 2 or 4. You could do {2,4} as well to length between two numbers (2 and 4 in this case)
[\/]: Character /
g : Global -- Or m: Multiline (Optional, see your requirements)
$: Anchor to end of string. (Optional, see your requirements)
^: Start of string. (Optional, see your requirements)
An example of use:
var regex = /^[0-9]{2}[\/][0-9]{2}[\/][0-9]{4}$/g;
var dates = ["2009-10-09", "2009.10.09", "2009/10/09", "200910-09", "1990/10/09",
"2016/0/09", "2017/10/09", "2016/09/09", "20/09/2016", "21/09/2016", "22/09/2016",
"23/09/2016", "19/09/2016", "18/09/2016", "25/09/2016", "21/09/2018"];
//Iterate array
dates.forEach(
function(date){
console.log(date + " matches with regex?");
console.log(regex.test(date));
});
Of course you can use as boolean:
if(regex.test(date)){
//do something
}
I use this function for dd/mm/yyyy format :
// (new Date()).fromString("3/9/2013") : 3 of september
// (new Date()).fromString("3/9/2013", false) : 9 of march
Date.prototype.fromString = function(str, ddmmyyyy) {
var m = str.match(/(\d+)(-|\/)(\d+)(?:-|\/)(?:(\d+)\s+(\d+):(\d+)(?::(\d+))?(?:\.(\d+))?)?/);
if(m[2] == "/"){
if(ddmmyyyy === false)
return new Date(+m[4], +m[1] - 1, +m[3], m[5] ? +m[5] : 0, m[6] ? +m[6] : 0, m[7] ? +m[7] : 0, m[8] ? +m[8] * 100 : 0);
return new Date(+m[4], +m[3] - 1, +m[1], m[5] ? +m[5] : 0, m[6] ? +m[6] : 0, m[7] ? +m[7] : 0, m[8] ? +m[8] * 100 : 0);
}
return new Date(+m[1], +m[3] - 1, +m[4], m[5] ? +m[5] : 0, m[6] ? +m[6] : 0, m[7] ? +m[7] : 0, m[8] ? +m[8] * 100 : 0);
}
Try using this..
[0-9]{2}[/][0-9]{2}[/][0-9]{4}$
this should work with this pattern DD/DD/DDDD where D is any digit (0-9)
((?=\d{4})\d{4}|(?=[a-zA-Z]{3})[a-zA-Z]{3}|\d{2})((?=\/)\/|\-)((?=[0-9]{2})[0-9]{2}|(?=[0-9]{1,2})[0-9]{1,2}|[a-zA-Z]{3})((?=\/)\/|\-)((?=[0-9]{4})[0-9]{4}|(?=[0-9]{2})[0-9]{2}|[a-zA-Z]{3})
Regex Compile on it
2012/22/Jan
2012/22/12
2012/22/12
2012/22/12
2012/22/12
2012/22/12
2012/22/12
2012-Dec-22
2012-12-22
23/12/2012
23/12/2012
Dec-22-2012
12-2-2012
23-12-2012
23-12-2012
If you are in Javascript already, couldn't you just use Date.Parse() to validate a date instead of using regEx.
RegEx for date is actually unwieldy and hard to get right especially with leap years and all.
For people who needs to validate years earlier than year 1900, following should do the trick. Actually this is same as the above answer given by [#OammieR][1] BUT with years including 1800 - 1899.
/^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((18|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((18|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/
Hope this helps someone who needs to validate years earlier than 1900, such as 01/01/1855, etc.
Thanks #OammieR for the initial idea.
Do the following change to the jquery.validationengine-en.js file and update the dd/mm/yyyy inline validation by including leap year:
"date": {
// Check if date is valid by leap year
"func": function (field) {
//var pattern = new RegExp(/^(\d{4})[\/\-\.](0?[1-9]|1[012])[\/\-\.](0?[1-9]|[12][0-9]|3[01])$/);
var pattern = new RegExp(/^(0?[1-9]|[12][0-9]|3[01])[\/\-\.](0?[1-9]|1[012])[\/\-\.](\d{4})$/);
var match = pattern.exec(field.val());
if (match == null)
return false;
//var year = match[1];
//var month = match[2]*1;
//var day = match[3]*1;
var year = match[3];
var month = match[2]*1;
var day = match[1]*1;
var date = new Date(year, month - 1, day); // because months starts from 0.
return (date.getFullYear() == year && date.getMonth() == (month - 1) && date.getDate() == day);
},
"alertText": "* Invalid date, must be in DD-MM-YYYY format"
I build this regular to check month 30/31 and let february to 29.
new RegExp(/^((0[1-9]|[12][0-9]|3[01])(\/)(0[13578]|1[02]))|((0[1-9]|[12][0-9])(\/)(02))|((0[1-9]|[12][0-9]|3[0])(\/)(0[469]|11))(\/)\d{4}$/)
I think, it's more simple and more flexible and enough full.
Perhaps first part can be contract but I Don't find properly.
This validates date like dd-mm-yyyy
([0-2][0-9]|(3)[0-1])(\-)(((0)[0-9])|((1)[0-2]))(\-)([0-9][0-9][0-9][0-9])
This can use with javascript like angular reactive forms
It can be done like this for dd/mm/yyyy:
^(3[01]|[12][0-9]|0[1-9])/(1[0-2]|0[1-9])/[0-9]{4}$
For mm/dd/yy, mm/dd/yyyy, dd/mm/yy, and dd/mm/yyyy:
Allowing leading zeros to be omitted:
^[0-3]?[0-9]/[0-3]?[0-9]/(?:[0-9]{2})?[0-9]{2}$
Requiring leading zeros:
^[0-3][0-9]/[0-3][0-9]/(?:[0-9][0-9])?[0-9][0-9]$
For more details: https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s04.html

javascript dynamic regex vs hard typed and captures

I've been at this for hours -- I think I need sleep... but no matter how I alter the expression javascript will only capture the 1st and 3rd elements:
var number = 09416;
var mat = "([0-9]+/[0-9]+/[0-9]+\\s+[0-9]+:[0-9]+)\\s+([A-Z]+)\\s+[0-9,]+\\s+(.*?"+number+".+)";
// month / day / year hour : min AMPM byte size filename containing number in middle
var pattern = new RegExp(mat,"gi");
var arr = ['09/07/2010 07:08 PM 1,465,536 BOL09416 BOL31.exe',
'09/06/2010 12:13 PM 110,225 BOL09416_BOL030.exe',
'09/08/2010 04:46 AM 60,564 BOL09416_BOL32.exe',
'09/08/2010 01:08 PM 63,004 bol09416_bol33.exe']
for (var i=0;i<arr.length;i++){
var match = pattern.exec(arr[i]);
alert(match);
}
It is all spaces (no tabs), I've rewriten the regex to be as explainatory as possible... It correctly matches on arr[0] and arr[2], but nulls on the other two.
Tried looking for possible typo's, trying different .+,.*,.+? etc. All online matchers show that it should be working: Example
Anybody have any ideas as to what I'm missing?
====================
Update:
Going through all the awesome suggestions I am stumped even further:
var match = arr[i].match(/([0-9]+\/[0-9]+\/[0-9]+\s+[0-9]+:[0-9]+)\s+([A-Z]+)\s+[0-9,]+\s+(.*?09416.+)/g);
gives match[0] = full string match[1] = undefined. Basically no captures.
where as:
var match = /([0-9]+\/[0-9]+\/[0-9]+\s+[0-9]+:[0-9]+)\s+([A-Z]+)\s+[0-9,]+\s+(.*?09416.+)/g.exec(arr[i]);
DOES return match[0] = full string, match[1] = date, and so on.
So I guess my real question is how to include dynamically made RegExpressions, and have multiple captures? As the only difference between:
var number = "09416";
var mat = "([0-9]+/[0-9]+/[0-9]+\\s+[0-9]+:[0-9]+)\\s+([A-Z]+)\\s+[0-9,]+\\s+(.*?09416.+)";
var pattern = new RegExp(mat,'g');
and
/([0-9]+\/[0-9]+\/[0-9]+\s+[0-9]+:[0-9]+)\s+([A-Z]+)\s+[0-9,]+\s+(.*?09416.+)/g.exec(arr[i]);
is that I hard-typed the number.
var number = 09416;
// month / day / year hour : min AMPM byte size filename containing number in middle
var mat = '^(\d{2}\/\d{2}\/\d{4})\s+(\d{2}:\d{2}\s*[AP]M)\s+((\d+[\d,]?))\s+(.' + number + '.*)$';
var pattern = new RegExp(mat);
var arr = ['09/07/2010 07:08 PM 1,465,536 BOL09416 BOL31.exe',
'09/06/2010 12:13 PM 110,225 BOL09416_BOL030.exe',
'09/08/2010 04:46 AM 60,564 BOL09416_BOL32.exe',
'09/08/2010 01:08 PM 63,004 bol09416_bol33.exe']
for (var i=0;i<arr.length;i++){
var match = arr[i].match(pattern);
console.log(match);
}
Use string.match instead of regex.exec.
Edited
I've removed the global and it worked like it should be. I've also rewritten the regex but it's quite close to yours (not a big deal).
Look at the output by firebug below:
["09/08/2010 04:46 AM ...,564 BOL09416_BOL32.exe", "09/08/2010", "04:46 AM", "60,564", "564", "BOL09416_BOL32.exe"]
0 "09/08/2010 04:46 AM ...,564 BOL09416_BOL32.exe" //whole match
1 "09/08/2010" //date
2 "04:46 AM" //time
3 "60,564" //bytes
4 "564" // last digit of bytes (i can't take this off. but it's harmless)
5 "BOL09416_BOL32.exe" //name of file
I would suggest you try Regexr to build the expression.
try this
([0-9]+/[0-9]+/[0-9]+ +?[0-9]+:[0-9]+) +?([A-Z]+) +?[0-9,]+ +?(.*?09416.*)
Try this regex:
new RegExp('([0-9]+/[0-9]+/[0-9]+\\s+[0-9]+:[0-9]+)\\s+(AM|PM)\\s+([0-9,]+)\\s+([^0-9]*'+number+'.+)','gi')
Time
AM/PM
File size
File name

Javascript: Add +1 to number that starts with 0 (like 01, 02, 03) and keep the zero

I like to add (+1) to a number. But problem is my number can sometimes have 0 preceding it. Like 01, 02, 03, 04. So I like result to be:
mockup01 + 1 = mockup02
mockup11 + 1 = mockup12
How can that be achieved? Example of how I would use it would be if I had filename named mockup_01.htm and change it to mockup_02.htm
Thanks!
Maybe this
next = (parseInt(number, 10) + 101).toString().substr(1)
to make a mockup_02.htm out of mockup_01 try this
newName = fileName.replace(/\d+(?=\.)/, function(n) {
return (parseInt(n, 10) + Math.pow(10, n.length) + 1).toString().substr(1)
});
this works with numbers of any length, e.g. mockup_0001, mockup_000001 etc
I'm not a javascript programmer, but it seems like you're mixing up presentation and internal representation. If the "01" is a string, with a corresponding integer variable, you can convert from the string to the integer, add 1, and then make a new string with the desired formatting. This is sometimes referred to as a model-view-controller pattern. The model is the integer variable - it models the internal behavior of numbers. The view is the string - it presents the number in a human readable fashion. The controller handles the numerical operations.
function next_id(input) {
var output = parseInt(input, 10)+1; // parse and increment
output += ""; // convert to string
while (output.length<2) output = "0"+output; // prepend leading zeros
return output;
}
var id = "00";
for (var i=0; i<20; i++) {
console.log(id);
id = next_id(id);
}

Categories

Resources