0

I have a strange timezone/date formatting issue that recently came up with some new code, and what makes it more strange is that it only affects two months - August and September.

The code takes a date string with UTC time formatted like this:
10-06-2017 09:29:15

And converts it to a new string with the same format but with local time. The zeroPad function ensures that the format remains the same.

We implemented it in March and everything worked fine. It's within Classic ASP on IIS9/Server 2012.

As soon as we got to August, it broke. 08-10-2017 09:33:06 becomes 12-09-2016 20:33:06.

Can anyone see what I've done wrong?

function jsConvert(dateString) {
  var patterns = dateString.split(/[\-\s:]/g);
  var date = new Date(parseInt(patterns[2]), 
  parseInt(patterns[0]) - 1,
  parseInt(patterns[1]),
  parseInt(patterns[3]),
  parseInt(patterns[4]),
  parseInt(patterns[5]));
  date.setTime(date.getTime() - getTimezoneOffset() * 60 * 1000);

  var result = zeroPad(date.getMonth() + 1);
  result += '-' + zeroPad(date.getDate());
  result += '-' + date.getFullYear();
  result += ' ' + zeroPad(date.getHours());
  result += ':' + zeroPad(date.getMinutes());
  result += ':' + zeroPad(date.getSeconds());

  return result;
}

function zeroPad(number) {
  return (number < 10) ? '0' + number : number;
}
  • Works for me (after adding `date.` in front of `getTimezoneOffset`), https://jsfiddle.net/xnomgrw8/ - outputs `08-10-2017 11:33:06` to console ... What is _your_ local timezone? – CBroe Aug 10 '17 at 11:29

2 Answers2

0

What are the units of time in your getTimezoneOffset() function?

Your code is written as though the getTimezoneOffset() function returns a number of minutes, since you are multiplying by 60 and then 1000, to get millseconds.

But if your getTimezoneOffset is returning seconds, you will be over-doing the multiplication and therefore jumping back too far in time.

I think it would have to be milliseconds, to jump back the distance you are getting. @CBroe above mentions that perhaps you mean the builtin getTimezoneOffset function, which is indeed in minutes. Perhaps you have a separate getTimezoneOffset function defined in your code elsewhere, that returns an answer in milliseconds? In which case CBroe's answer fixes it.

My next suggestion would be to add lines of debugging code

For example, could you add the following?

At the beginning, add console.log("A",dateString).

After var patterns = dateString.split(/[\-\s:]/g); add a line console.log("B",patterns);.

After var date = ...(patterns[5])); add a line console.log("C",date);.

After date.setTime...1000); add a line console.log("D",date); console.log("E",getTimezoneOffset());.

If you show us the output of these lines, we should be able to pinpoint the problem easily. I have included item E because I am just wondering if there is yet another getTimezoneOffset() function in your system, which we are not aware of, or something. Seeing its value will help reassure everyone.

Meanwhile can you confirm the time zone you are running the code in? I am guessing it is in the USA rather than Europe, from your preference for putting month before the day?

ProfDFrancis
  • 8,816
  • 1
  • 17
  • 26
  • It returns milliseconds... function getTimezoneOffset(){ var d = new Date(); return d.getTimezoneOffset();} – Mark Sinford Aug 10 '17 at 11:50
  • So you are effectively using the builtin getTimezoneOffset() function. This returns the offset in minutes (not milliseconds). On that basis, the wild time displacement you are finding is not the fault of that step in your code. – ProfDFrancis Aug 11 '17 at 10:50
0

So as it turns out this is a known, albeit obscure issue. It has to do with the fact that parseInt assumes that numbers with leading zeros are NOT base 10, but instead radix. It's well documented here: Javascript parseInt() with leading zeros

Once I made the change to:

parseInt(patterns[2]**, 10**);

All was good.

Thanks for the input.