Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

390
Views
Regex validation for time tracking

I am trying to validate a string the way it is done in Jira in Javascript. I'm trying to replicate how it is validated in Jira. I am guessing I could do this with Regex but I am not sure how.

A user can type a string in the format of "1d 6h 30m" which would mean 1 day, 6 hours, 30 minutes. I do not need the weeks for my use case. I want to show an error if the user uses an invalid character (anything except 'd','h','m', or ' '). Also the string must separate the time durations by spaces and ideally I would like to force the user to enter the time durations in descending order meaning '6h 1d' would be invalid because the days should come first. Also the user does not have to enter all information so '30m' would be valid.

This is my code for getting the days, hours and minutes which seems to work. I just need help with the validation part.

let time = '12h 21d 30m'; //example
let times = time.split(' ');
let days = 0;
let hours = 0;
let min = 0;
for(let i = 0; i < times.length; i++) {
    if (times[i].includes('d')){
        days = times[i].split('d')[0];
    }
    if (times[i].includes('h')){
        hours = times[i].split('h')[0];
    }
    if (times[i].includes('m')){
        min = times[i].split('m')[0];
    }
}
console.log(days);
console.log(hours);
console.log(min);

enter image description here

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Based on your comment, I have added a validation regex to be run first before running the match regex.

For validation, you want

/^(\d+[d]\s+)?(\d+[h]\s+)?(\d+[m]\s+)?(\d+[s]\s+|$)?/

For extracting values, you want

/([\d]+[dhms]\s+|$)/g

You can then use String.match with this regular expression, iterating through all the matches add adding time based on the time letter at the end

about 4 years ago · Juan Pablo Isaza Report

0

const INPUT = "12h 21d  30s";

checkTimespanFormat(INPUT);

if (checkTimespanKeysOrder(INPUT, true))
  console.log(`${INPUT} keys order is valid`);
else console.log(`${INPUT} keys order is NOT valid`);
//******************************************************************

/**
 * Ensures that time keys are:
 * - Preceeded by one or two digits
 * - Separated by one or many spaces
 */
function checkTimespanFormat(timespanStr, maltiSpacesSeparation = false) {
  // timespan items must be separated by 1 space
  if (maltiSpacesSeparation) timespanStr = timespanStr.toLowerCase().split(" ");
  // timespan items must be separated by one or many space
  else timespanStr = timespanStr.toLowerCase().split(/ +/);

  // timespan items must be formatted correctly
  timespanStr.forEach((item) => {
    if (!/^\d{1,2}[dhms]$/.test(item)) console.log("invalid", item);
    else console.log("valid", item);
  });
}

/**
 * Validates:
 * - Keys order
 * - Duplicate keys
 */
function checkTimespanKeysOrder(timespanStr) {
  const ORDER = ["d", "h", "m", "s"];

  let timeKeysOrder = timespanStr
    .replace(/[^dhms]/g, "") // Removing non time keys characters
    .split("") // toArray
    .map((char) => {
      return ORDER.indexOf(char); // Getting the order of time keys
    });

  for (i = 0; i < timeKeysOrder.length - 1; i++)
    if (timeKeysOrder.at(i) >= timeKeysOrder.at(i + 1)) return false;
  return true;
}

about 4 years ago · Juan Pablo Isaza Report

0

Here's my take at the problem:

  1. match minutes ([1-5]?[\d])m, with eligible values in range [0,59]
  2. match hours ([1]?[\d]|2[0-3])h , with eligible values in range [0,23]
  3. match days ([1-9]|[1-9][\d])d, with eligible values in range [1,99]

Then we can encapsulate regex for days in hours and regex for hours in minutes to make sure that we have formats like {dd}d {hh}h {mm}m, {hh}h {mm}m, {mm}m:

"(((([1-9]|[1-9][\d])d )?([1]?[\d]|2[0-3])h )*([1-5]?[\d])m)"

Corner cases include inputs with zeros like 00m, 00d 00m, 01h 00d 00m. In order to reject the former two and accept the last one, we can negate the values 00m and 00d when the preceeding patterns are not found.

Final regex to use:

"(?!0m)(((?!0h)(([1-9]|[1-9][\d])d )?([1]?[\d]|2[0-3])h )*([1-5]?[\d])m)"

Check for:

  • days in Group 4
  • hours in Group 5
  • minutes in Group 6

Tested at https://regex101.com.

Does it solve your problem?

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!