Unable to do Date string to Date object conversion in k6

I have been trying to do some date manipulation in k6 script but I am not able to convert a date string to a date object. The thing is that I am getting two dates like initialDate and FinalDate from an API. I want to calculate this difference inside k6 script. The dateString format coming from the API response is like this: ‘Jul 10, 2023 3:17:36 AM’. When converting this to a dateObject it shows ‘Invalid Date’ in the console.

Here is an example script:

import http from 'k6/http';
import { sleep } from 'k6';

const dateDiff = (ds1, ds2) => {
    const d1 = new Date(ds1);
    const d2 = new Date(ds2);
    const timeDiff = d2.getTime() - d1.getTime();
    return timeDiff / 1000;
};

export default function () {
// Some REST API call
  http.get('https://test.k6.io');
  sleep(1);

// Post call making some calculations
  const ds1 = 'Jul 12, 2023 3:17:36 AM';
  const ds2 = 'Jul 12, 2023 3:18:22 AM';
  console.log(dateDiff(ds1,ds2));
}

The output of this script shows NaN because the dateString was not converted as it should.
Although, this same date manipulation works in any normal JS online compiler.

I am new to k6, I don’t understand why it is showing this behaviour. Can anyone propose a workaround for this?

Hi @blaZe

Welcome to the community forum :tada:

What your endpoint returns seem to not be an ISO standard date. If you were able to get that from your endpoint, I believe const timestamp = Date.parse('2023-07-12T03:17:36.000Z') would work. What does not work is getting a Timestamp from a custom date format like Jul 12, 2023 3:17:36 AM.

We discussed this internally, and we don’t think this is working in the browser as standard JavaScript behavior. Browsers implement quite a lot of additional functionality, and that could be part of it. The specification does not forbid supporting additional formats. However, there is only one format that is required to be supported.

Date.parse() - JavaScript | MDN goes into some more details, and it is not expected to be working and will need to be added to goja, which is what k6 uses to interpret the JS scripts and execute them in the go runtime.

That said, the code would work with a date in a standard format, so if you were able to configure the request to return that, the following code would work:

const dateDiff = (ds1, ds2) => {
  const d1 = Date.parse(ds1);
  const d2 = Date.parse(ds2);
  const timeDiff = d2 - d1;
  return timeDiff / 1000;
};

export default function () {
  const ds1 = '2023-07-12T03:17:36.000Z';
  const ds2 = '2023-07-12T03:18:22.000Z';
  console.log("diff:", dateDiff(ds1,ds2));
}

If you are probably not able to do that, until there is an option to parse dates specifying a custom format, and goja implements it, we’d suggest parsing this format in a function in your script. Which you can later replace if this becomes available. Something like this (better packaged and adjusted for your case):

function getMonthIndex(monthString) {
  const months = [
    'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
  ];
  return months.indexOf(monthString);
}

function parseDate(dateString) {
  const dateParts = dateString.split(' ');
  const month = getMonthIndex(dateParts[0]);
  const day = parseInt(dateParts[1].replace(',', ''));
  const year = parseInt(dateParts[2]);
  const time = dateParts[3];
  const hour = parseInt(time.split(':')[0]);
  const minute = parseInt(time.split(':')[1]);
  const second = parseInt(time.split(':')[2]);
  const isAM = dateParts[4] === 'AM';
  return new Date(year, month, day, hour + (isAM ? 0 : 12), minute, second);
}

function dateDiff(date1, date2) {
  return (parseDate(date2) - parseDate(date1)) / 1000;
}

export default function () {
  const ds1 = 'Jul 12, 2023 3:17:36 AM';
  const ds2 = 'Jul 12, 2023 3:18:22 AM';
  console.log("diff:", dateDiff(ds1, ds2));
}

I haven’t tested that, as k6 has limited support for node modules, though you might also try importing the moment module and see if that works for you. It seems to include js-joda and probably parsing specifying a custom date format.

I hope this helps :bowing_woman:

Cheers!

2 Likes