I have the following time format 2h 34m 22s and I'm parsing it as 02:34:22 using this code:
const splitterArray = '2h 34m 22s'.split(' ');
let h = '00', m = '00', s = '00';
splitterArray.forEach(val => {
if (val.includes('h')) {
h = val.replace('h', '');
} else if (val.includes('m')) {
m = val.replace('m', '');
}
else if (val.includes('s')) {
s = val.replace('s', '');
}
});
console.log(`${h}:${m}:${s}`);
This also handles the case when there's only minutes and seconds, or only hours and seconds or only hours and minutes.
Just checking if there's a better way to do it like a library or so (maybe to accept days too).
You could match in wanted order and get the result with colons.
function convert(string) {
return Array
.from('hms', p => (string.match(new RegExp(`\\d+(?=${p})`))?.[0] || '') .padStart(2, '0'))
.join(':');
}
console.log(convert('2h 34m 22s'));
I suggest using the moment library. it has plenty of examples and documentation for all of your time formatting and parsing needs:
https://momentjs.com/
I have a time string and I want to convert it to have : between the hour and minutes. Any suggestions on how to take the sting and change it. I’m assuming I need to use regular expression but not sure how to format that code. Any suggestions would be great.
var number = '1340';
moment(number).format('hh:mm')
console.log(number)
// The output I want would be 13:40
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
Stick a : before the last 2 digits. This makes the assumption that your minutes are padded with zeroes if not 2 digits long:
console.log('1340'.replace(/\d{2}$/, m => ':' + m));
First off, in the code you show you are outputing the original string not the result from moment.js.
If you want to use moment, you'll need to tell it what format your string is:
var number = '1340';
var time = moment(number, 'hhmm').format('hh:mm')
console.log(time)
var number = '1340';
console.log(number.slice(0, 2)+":"+number.slice(2));
const number = "1340";
const time = `${number.substring(0,2)}:${number.substring(2,4)}`;
console.log(time);
Moment needs a date.
You want something like this
const pad = num => ("00"+num).slice(-2);
const hhmm = str => {
const mm = str.slice(-2)
const hh = str.slice(0,-2)
return `${pad(hh)}:${pad(mm)}`;
};
console.log(hhmm('1340'))
console.log(hhmm('340'))
console.log(hhmm('40'))
console.log(hhmm('0'))
console.log(hhmm(''))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
I am receiving a string in this format 'HH:mm:ss'. I would like to remove the leading zeros but always keeping the the last four character eg m:ss even if m would be a zero. I am formatting audio duration.
Examples:
00:03:15 => 3:15
10:10:10 => 10:10:10
00:00:00 => 0:00
04:00:00 => 4:00:00
00:42:32 => 42:32
00:00:18 => 0:18
00:00:08 => 0:08
You can use this replacement:
var result = yourstr.replace(/^(?:00:)?0?/, '');
demo
or better:
var result = yourstr.replace(/^0(?:0:0?)?/, '');
demo
To deal with Matt example (see comments), you can change the pattern to:
^[0:]+(?=\d[\d:]{3})
If you use 1 h instead of two you will not get the leading 0.
h:mm:ss
Another option is to use moment.js libary.
This supports formats such as
var now = moment('1-1-1981 2:44:22').format('h:mm:ss');
alert(now);
http://jsfiddle.net/8yqxh5mo/
You could do something like this:
var tc =['00:03:15', '10:10:10','00:00:00','04:00:00','00:42:32','00:00:18','00:00:08'];
tc.forEach(function(t) {
var y = t.split(":");
y[0] = y[0].replace(/^[0]+/g, '');
if(y[0] === '') {
y[1] = y[1].replace(/^0/g, '');
}
var r = y.filter(function(p) {return p!=='';}).join(':');
console.log(r);
});
Divide the time in 3 parts. Remove the leading zeroes from first part, if the the first part is empty remove the leading zeroes from the second part otherwise keep it. Then join all of them discarding the empty strings.
I had a problem with ZUL time when simply format with one small 'h' moment(date).format('h:mm A') cuts first digit from time:
and my const arrivalTime = "2022-07-21T12:10:51Z"
const result = moment(arrivalTime).format(('h:mm A')) // 2:10 PM
Solution for that was converting that to ISO format and then format:
const arrivalTimeIsoFormat = arrivalTime.toISOString()
const result = moment(arrivalTimeIsoFormat, "YYYY-MM-DDTHH:mm:ss.SSS").format(('h:mm A')) // 12:10 PM
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
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