Cumbersome time parsing in JavaScript

107 views Asked by At

I need a function to convert time in text from a format with day-part letters to digits. E.g. 4:15PM -> 16:15, 4:15AM -> 4:15AM. Currently I have the following solution

function formatTime(text){
 var find = '([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9] (AM|PM)';
 
 var reg = new RegExp(find, 'g');
 
 pos = 0;

 var result;
 var formatedText = "";
 while((result = reg.exec(text)) !== null) {
  if(result[2] == "PM"){
   var hours= parseInt(result[0], 10);
   hours = hours + 12;
   var hoursStr = hours.toString();
   var newTime = hoursStr + result[0].substring(result[1].length,result[0].length - 3);
   
   formatedText += newTime;
   pos = reg.lastIndex;
  } else {
   formatedText += text.replace("AM","").substring(pos, reg.lastIndex);
   pos = reg.lastIndex;
  }
 }
 
 if(pos < text.length){
  formatedText += text.substring(pos, text.length);
 }
 
 return formatedText;
}

console.log(formatTime("Some Text (11:00AM - 1:00PM)"));

I makes nicely cases like console.log(formatTime("Some Text (11:00AM - 1:00PM)"));

But I strugle to make it process console.log(formatTime("Some Text (11:00 AM - 1:00 PM)"));

2

There are 2 answers

1
Alex T On BEST ANSWER

This works for your examples. I've added \\s? to the regex and made a minor change in the logic of cutting time (-2 instead of -3). Also I've moved variables definition to the beginning of the function to reflect hoisting in JavaScript.

function formatTime(text){
    var find = '([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]\\s?(AM|PM)';            
    var reg = new RegExp(find, 'g');            
    var pos = 0;
    var formatedText = "";
    var result, hours, hoursStr, newTime;           

    while ((result = reg.exec(text)) !== null) {
        if (result[2] === "PM") {
            hours= parseInt(result[0], 10);
            hours = hours + 12;
            hoursStr = hours.toString();
            newTime = hoursStr + result[0].substring(result[1].length, result[0].length - 2);

            formatedText += newTime;                    
        } else {
            formatedText += text.replace("AM","").substring(pos, reg.lastIndex);

        }

        pos = reg.lastIndex;
    }

    if (pos < text.length) {
        formatedText += text.substring(pos, text.length);
    }

    return formatedText;
}
5
mike510a On

Here's an easier way to do this: Just use two functions. One to convert the hours, and another to match against PM times along with the replace() function.

Easy does it...

function convertTime12to24(time12h) {
  const [time, modifier] = time12h.split(' ');

  let [hours, minutes] = time.split(':');

  if (hours === '12') {
    hours = '00';
  }

  if (modifier === 'PM') {
    hours = parseInt(hours, 10) + 12;
  }

  return hours + ':' + minutes;
}


function formatTime(i_string) {
  console.log(i_string.replace(/([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])(PM)/gi, function newDate(x) {

    return convertTime12to24(x.replace("PM", " PM"))
  }));
}
formatTime("The time is now 4:15PM");
formatTime("The time is now 12:15PM");
formatTime("The time is now 4:00AM");
formatTime("The time is now 12:00AM");
formatTime("The time is now 11:00PM");