Search code examples
javascriptdatecucumbermomentjscucumberjs

How can I parse a string with a date calculation like now + 1 days into a date object?


I'm currently using Cucumber to define our test cases in string based feature files. The integration tests will run against a wiremock stub which has date calculations like: "{{now offset='+15 minutes'}}"

I want to validate that the date and time I'm getting from the wiremock stub are displayed correctly, that the date and time are correct and that the table is ordered properly based on that date and time.

We currently have our own implementation to get now +/- X days. That uses some regex and only supports days. I can expand that code and add minutes to that but I would much rather use a library or a standardized piece of code that can parse all date calculations. I haven't been able to find it and would love some suggestions on how to solve this.

To give you an idea of what I'm working with at the moment:

function stringReplaceNow(string) {
  var regex = /<now:([A-Z-]+):?((\+|-)([0-9]+))?>/gi;

  return string.replace(regex, function (match, format, shouldModify, modification, modAmount) {
    if (modification === '+') {
      return moment().add(modAmount, 'days').format(format);
    } else if (modification === '-') {
      return moment().subtract(modAmount, 'days').format(format);
    }
    return moment().format(format);
  });
}

In our cucumber tests it gets used like this, it will get the current date and subtract the days accordingly:

| Name             | Datetime            | State      |
| Johnson          | <now:DD-MM-YYYY:-2> | Processing |
| Minter           | <now:DD-MM-YYYY:-3> | Processing |
| Brown            | <now:DD-MM-YYYY:-5> | Done       |

Solution

  • There are no standards for date calculations so I doubt you'll find a library for it. However you can use parts of the existing standards so simplify your custom date calculations.

    In this instance, rather then developing your own format consider using the ISO-8601 duration format. You can then use existing libraries to parse the duration format and add it to the current time.

    Examples:

    "PT20.345S" -- parses as "20.345 seconds"
    "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
    "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
    "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
    "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
    "PT-6H3M"    -- parses as "-6 hours and +3 minutes"
    "-PT6H3M"    -- parses as "-6 hours and -3 minutes"
    "-PT-6H+3M"  -- parses as "+6 hours and -3 minutes"