From 3f675fe524eece31f39fb68601d2d2d7d5720941 Mon Sep 17 00:00:00 2001 From: Dan Vanderkam Date: Tue, 13 Mar 2012 19:12:45 -0400 Subject: [PATCH] Fix issue 255: date supplied as YYYY-MM-DD shows previous day's date... JavaScript date parsing is stunningly complex. This was broken by https://github.com/danvk/dygraphs/commit/769e8bc7b8799385e2677b26a5c0a72e839f44ca The underlying issue is that new Date("YYYY-MM-DD") parses the date in UTC, but new Date("YYYY/MM/DD") parses it in the local time zone. --- auto_tests/misc/local.html | 1 + auto_tests/tests/no_hours.js | 77 ++++++++++++++++++++++++++++++++++++++++++++ dygraph-utils.js | 14 ++++++-- 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 auto_tests/tests/no_hours.js diff --git a/auto_tests/misc/local.html b/auto_tests/misc/local.html index ae39e7f..6db0207 100644 --- a/auto_tests/misc/local.html +++ b/auto_tests/misc/local.html @@ -37,6 +37,7 @@ + diff --git a/auto_tests/tests/no_hours.js b/auto_tests/tests/no_hours.js new file mode 100644 index 0000000..4f782d5 --- /dev/null +++ b/auto_tests/tests/no_hours.js @@ -0,0 +1,77 @@ +/** + * @fileoverview Tests that we don'show specify hours, minutes or seconds + * in your dates if you don't specify them. This can get mixed up becaues of + * time zones. + * + * @author danvk@google.com (Dan Vanderkam) + */ +var noHoursTestCase = TestCase("no-hours"); + +noHoursTestCase.prototype.setUp = function() { + document.body.innerHTML = "
"; +}; + +noHoursTestCase.prototype.tearDown = function() { +}; + +function getLegend() { + var legend = document.getElementsByClassName("dygraph-legend")[0]; + return legend.textContent; +} + +noHoursTestCase.prototype.testNoHours = function() { + var opts = { + width: 480, + height: 320 + }; + var data = "Date,Y\n" + + "2012/03/13,-1\n" + + "2012/03/14,0\n" + + "2012/03/15,1\n" + + "2012/03/16,0\n" + ; + + var graph = document.getElementById("graph"); + var g = new Dygraph(graph, data, opts); + + g.setSelection(0); + assertEquals("2012/03/13: Y:-1", getLegend()); + + g.setSelection(1); + assertEquals("2012/03/14: Y:0", getLegend()); + + g.setSelection(2); + assertEquals("2012/03/15: Y:1", getLegend()); + + g.setSelection(3); + assertEquals("2012/03/16: Y:0", getLegend()); +}; + +noHoursTestCase.prototype.testNoHoursDashed = function() { + var opts = { + width: 480, + height: 320 + }; + var data = "Date,Y\n" + + "2012-03-13,-1\n" + + "2012-03-14,0\n" + + "2012-03-15,1\n" + + "2012-03-16,0\n" + ; + + var graph = document.getElementById("graph"); + var g = new Dygraph(graph, data, opts); + + g.setSelection(0); + assertEquals("2012/03/13: Y:-1", getLegend()); + + g.setSelection(1); + assertEquals("2012/03/14: Y:0", getLegend()); + + g.setSelection(2); + assertEquals("2012/03/15: Y:1", getLegend()); + + g.setSelection(3); + assertEquals("2012/03/16: Y:0", getLegend()); +}; + diff --git a/dygraph-utils.js b/dygraph-utils.js index 689f8eb..c6c3a60 100644 --- a/dygraph-utils.js +++ b/dygraph-utils.js @@ -494,9 +494,17 @@ Dygraph.dateParser = function(dateStr) { var dateStrSlashed; var d; - // Let the system try the format first. - d = Dygraph.dateStrToMillis(dateStr); - if (d && !isNaN(d)) return d; + // Let the system try the format first, with one caveat: + // YYYY-MM-DD[ HH:MM:SS] is interpreted as UTC by a variety of browsers. + // dygraphs displays dates in local time, so this will result in surprising + // inconsistencies. But if you specify "T" or "Z" (i.e. YYYY-MM-DDTHH:MM:SS), + // then you probably know what you're doing, so we'll let you go ahead. + // Issue: http://code.google.com/p/dygraphs/issues/detail?id=255 + if (dateStr.search("-") == -1 || + dateStr.search("T") != -1 || dateStr.search("Z") != -1) { + d = Dygraph.dateStrToMillis(dateStr); + if (d && !isNaN(d)) return d; + } if (dateStr.search("-") != -1) { // e.g. '2009-7-12' or '2009-07-12' dateStrSlashed = dateStr.replace("-", "/", "g"); -- 2.7.4