'Insert colon separator into timings ( i.e convert 1230a to 12:30a and 1430 to 14:30 )

I have a requirement in my project whereby we have some input boxes and we are supposed to enter timings.

Timings can be entered in any format i.e 12:30a or 1230 or 1430 or 14:30.

The problem with timings entered in 1230 or 1430 format is that I cannot properly parse them via Data.parse('1230'). I have to parse the timings to convert them into date objects so that i can perform more operations on them.

So for this requirement I have to enter a colon between these timings.I.E convert 1230 to 12:30 and 1430 to 14:30.

Timings I have to Support :

12 Hour : 1230a,1230am,12:30a,12:30am

24 Hour : 1430,14:30



Solution 1:[1]

As others have mentioned, you can use the regex /\b(\d{1,2})(\d{2})/g and replace it with $1:$2. You requested an explanation, which you're completely right to do.

Javascript code:

var str = '430a';

var newStr = str.replace(/\b(\d{1,2})(\d{2})/g, '$1:$2');

console.log(newStr); // "4:30a"

Regex autopsy:

  • / - The start of the regex - shows javascript that this is a regex - this needs to be repeated at the end
  • \b - a word boundary, meaning a space, a period, a comma, a start of the string and the likes - it means we don't match b182 as b is not a boundary
  • (\d{1,2}) - a capturing group matching a digit matched 1 to 2 times (both inclusive). Will match eg. "2" and "24"
  • (\d{2}) - a capturing group matching a digit always matched 2 times. Will match eg. "30"
  • / - The end of the regex - it also is the separator for our modifier
  • g - Our modifier - this means we'll replace ANY occurence and not simply the first one

When we replace with $1:$2 this means "the content of the first capturing group ($1), followed by a colon (:), followed by the content of the second capturing group ($2)".

Transformation:

1430             -> 14:30
1230a            -> 12:30a
1230am           -> 12:30am
430a             -> 4:30a
The year is 2015 -> The year is 20:15
123456           -> 12:3456
Blink182         -> Blink182 (untouched)
Blink 182        -> Blink 1:82

DEMO

Solution 2:[2]

I made an answer that takes AM/PM into account as well:

var tests = ['1230a','12:30am','1230pm','1230p','14','14:30', '130pm'];
//Regex to split text and numbers:
var regex = /(^\d{1,2}):?(\d{2})(\D*)$/;
console.log(tests);
tests.map(function(t) {
	var r = regex.exec(t);
	var date;
	if(r){//We have a parsable date
		//First group is hours:
		var hours = parseInt(r[1], 10);
		//Second group is minutes:
		var minutes = parseInt(r[2], 10);
		//If theres text we apply some rules:
		var spec = (r[3][0]||'').toLowerCase();
		if(spec == 'p' && hours !== 12){
			hours += 12;
		}
		else if(spec == 'a' && hours == 12){
			hours = 0;
		}
		//Here we construct the date:
		date = new Date();
		date.setHours(hours);
		date.setMinutes(minutes);
		date.setSeconds(0);
	}
	//If no match we return undefined:
	console.log(t + ': ', date);
	return date;
});

Solution 3:[3]

You can try the following regex:

var re = /^(\d{1,2})(\d{2})/; 
var str = '1430';
var subst = '$1:$2'; 

var result = str.replace(re, subst);

See demo.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 pederOverland
Solution 3 h2ooooooo