0

I've got an odd situation going on here. I've got the following JSON being passed to the time line control:

[
  {
    "UserId": 2,
    "ItemId": 3,
    "ItemText": null,
    "ItemDate": "2014-06-09T18:51:37",
    "ItemDateEnd": null,
    "OutcomeScore": null
  },
...
]

This is a simple of array of items that I pass to the control to render. In Firefox this renders perfectly, no problems whatsoever. However, Every other browser I've tried it on shows the items +1 hour. I've tried it in Opera, Chrome and IE9 and they are all showing the same problem apart from Firefox. The now time displays as expected on all browsers.

Interestingly I'm in GMT summer time at the moment which is +1h ... but why would this selectively effect browsers differently?

Each browser is running exactly the same query and getting exactly the same JSON. I'm very confused and not even sure where to start looking.

I'm running v2.5.0 of the time line. I've tried updating to the latest version and the same thing occured so I rolled back to 2.5.0 to get the solved before working on getting the latest version integrated into the page.

Anyone seen this and have a solution?

Jammer
  • 9,969
  • 11
  • 68
  • 115
  • Interestingly it appears that all browsers other than FireFox will convert the date shown above when converting to date object like `Date(dataItem.ItemDate)` using the current GMT offset added meaning 18:51:37 becomes 19:51:37 ... – Jammer Jun 09 '14 at 19:19

2 Answers2

1

Creating Date objects from strings is unreliable, as you have observed. You should manually parse those strings into Date objects, like this:

// assumes date string is in the format "yyyy-MM-ddTHH:mm:ss"
var dateMatch = dataItem.ItemDate.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/);
var year = parseInt(dateMatch[1], 10);
var month = parseInt(dateMatch[2], 10) - 1; // convert to javascript's 0-indexed months
var day = parseInt(dateMatch[3], 10);
var hours = parseInt(dateMatch[4], 10);
var minutes = parseInt(dateMatch[5], 10);
var seconds = parseInt(dateMatch[6], 10);
var date = new Date(year, month, day, hours, minutes, seconds);
asgallant
  • 26,060
  • 6
  • 72
  • 87
  • Yes, as soon as I spotted what was going on a made further use of `moment.js` as I have it in the kit bag on the site already. – Jammer Jun 09 '14 at 21:56
  • What is still confused is that FireFox was the only browser to not display the discrepancy. – Jammer Jun 09 '14 at 21:57
  • All browsers interpret the strings differently (and a single browser can interpret them differently in different regions as well!). Firefox creates a date in your local time zone; Chrome assumes the string is GMT time, and then adjusts to your local time. The date string `'05/06/2014'` is May 6, 2014 to most browsers in the US, but June 5, 2014 to most browsers in Europe. Since the behavior is so variable, I always recommend avoiding using the browser's string parsing. – asgallant Jun 09 '14 at 22:14
1

First, note that the Timeline of the CHAP Links library does not support strings as Date, you should provided Dates or a timestamp with a Number (note that the successor of the Timeline, vis.js, does support strings as date). Strings as Date work nowadays because most browsers now support creating dates from an ISO date string.

The issue you have is because you provide an ISO Date String without time zone information. Apparently not all browsers have the same default behavior in that case. Enter the following in a JavaScript console in both Firefox and an other browser:

new Date("2014-06-09T18:51:37").toISOString() 
// output is ambiguous, time zone information missing

and you will see them adding timezone information in different ways. To prevent these kind of ambiguities, you should provide timezone information yourself. To specify the time in UTC, add a Z to the end of the string:

new Date("2014-06-09T18:51:37Z").toISOString()  
// output is unambiguous
Jos de Jong
  • 6,602
  • 3
  • 38
  • 58