-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Dates as dates #1078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Dates as dates #1078
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
d4bb89d
improve dateTime2ms edge cases and standardize BADNUM and FP_SAFE con…
alexcjohnson 9e27955
switch date axes to use date strings for range and tick0
alexcjohnson 00138aa
Merge branch 'master' into dates-as-dates
alexcjohnson 9784b3b
axe parseDate - moved to streambed
alexcjohnson 1db4448
refactor dates handling to use date strings as much as possible
alexcjohnson 5ff9722
Merge branch 'master' into dates-as-dates
alexcjohnson c045bc5
wider acceptance range for mapbox plot size test so it works locally
alexcjohnson 3dd294f
fix for range slider tests with new axis range machinery
alexcjohnson 451ee24
fix date axis ranges and date interactions in gl2d
alexcjohnson 9ccde7e
Merge branch 'master' into dates-as-dates
alexcjohnson 51a0563
lib/constants -> constants/numerical
alexcjohnson 5ccd083
td -> gd once and for all
alexcjohnson e63ea3b
test and fix shape default positioning
alexcjohnson 2e9dbad
fix date and log axis manual tick0/dtick handling
alexcjohnson 37d52fe
fix handling of default tick0 with dtick for date axes
alexcjohnson 55b313c
get rid of '2012-01-22 12h' tick format and smarter date suffix handling
alexcjohnson b7121c3
fix #1058 - make sure no date ever returns sub-100microsec precision
alexcjohnson 03b4a0c
Merge branch 'master' into dates-as-dates
alexcjohnson dd0940a
fix _forceTick0 error
alexcjohnson f629f71
update baseline with new date tick format
alexcjohnson a29ce33
fix images on date axes, and standardize axis object names
alexcjohnson 065ac8a
fix annotation drag on date axes, and test date/log annotations
alexcjohnson 4a0a866
Merge branch 'master' into dates-as-dates
alexcjohnson 7679483
update jasmine test of annotation visibility & autorange
alexcjohnson 0d61fcc
Merge branch 'master' into dates-as-dates
alexcjohnson 5e11571
merge lint
alexcjohnson d807259
add ax.r2p and ax.p2r
alexcjohnson 05c762d
date interval milliseconds constants
alexcjohnson 1b0e133
documentation updates
alexcjohnson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
improve dateTime2ms edge cases and standardize BADNUM and FP_SAFE con…
…stants
- Loading branch information
commit d4bb89d788a68c78c1b6dcad76a84c4e9241858b
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Copyright 2012-2016, Plotly, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the MIT license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
'use strict'; | ||
|
||
|
||
module.exports = { | ||
/** | ||
* Standardize all missing data in calcdata to use undefined | ||
* never null or NaN. | ||
* That way we can use !==undefined, or !== BADNUM, | ||
* to test for real data | ||
*/ | ||
BADNUM: undefined, | ||
|
||
/* | ||
* Limit certain operations to well below floating point max value | ||
* to avoid glitches: Make sure that even when you multiply it by the | ||
* number of pixels on a giant screen it still works | ||
*/ | ||
FP_SAFE: Number.MAX_VALUE / 10000 | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,26 +11,32 @@ | |
|
||
var d3 = require('d3'); | ||
var isNumeric = require('fast-isnumeric'); | ||
|
||
var BADNUM = require('./constants').BADNUM; | ||
|
||
/** | ||
* dateTime2ms - turn a date object or string s of the form | ||
* YYYY-mm-dd HH:MM:SS.sss into milliseconds (relative to 1970-01-01, | ||
* per javascript standard) | ||
* may truncate after any full field, and sss can be any length | ||
* even >3 digits, though javascript dates truncate to milliseconds | ||
* returns false if it doesn't find a date | ||
* returns BADNUM if it doesn't find a date | ||
* | ||
* Expanded to support negative years to -9999 but you must always | ||
* give 4 digits, except for 2-digit positive years which we assume are | ||
* near the present time. | ||
* Note that we follow ISO 8601:2004: there *is* a year 0, which | ||
* is 1BC/BCE, and -1===2BC etc. | ||
* | ||
* 2-digit to 4-digit year conversion, where to cut off? | ||
* from http://support.microsoft.com/kb/244664: | ||
* 1930-2029 (the most retro of all...) | ||
* but in my mac chrome from eg. d=new Date(Date.parse('8/19/50')): | ||
* 1950-2049 | ||
* by Java, from http://stackoverflow.com/questions/2024273/: | ||
* now-80 - now+20 | ||
* now-80 - now+19 | ||
* or FileMaker Pro, from | ||
* http://www.filemaker.com/12help/html/add_view_data.4.21.html: | ||
* now-70 - now+30 | ||
* now-70 - now+29 | ||
* but python strptime etc, via | ||
* http://docs.python.org/py3k/library/time.html: | ||
* 1969-2068 (super forward-looking, but static, not sliding!) | ||
|
@@ -39,8 +45,8 @@ var isNumeric = require('fast-isnumeric'); | |
* they can learn the hard way not to use 2-digit years, as no choice we | ||
* make now will cover all possibilities. mostly this will all be taken | ||
* care of in initial parsing, should only be an issue for hand-entered data | ||
* currently (2012) this range is: | ||
* 1942-2041 | ||
* currently (2016) this range is: | ||
* 1946-2045 | ||
*/ | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. very nice here. |
||
exports.dateTime2ms = function(s) { | ||
|
@@ -49,63 +55,96 @@ exports.dateTime2ms = function(s) { | |
if(s.getTime) return +s; | ||
} | ||
catch(e) { | ||
return false; | ||
return BADNUM; | ||
} | ||
|
||
var y, m, d, h; | ||
// split date and time parts | ||
var datetime = String(s).split(' '); | ||
if(datetime.length > 2) return false; | ||
if(datetime.length > 2) return BADNUM; | ||
|
||
var p = datetime[0].split('-'); // date part | ||
if(p.length > 3 || (p.length !== 3 && datetime[1])) return false; | ||
|
||
var CE = true; // common era, ie positive year | ||
if(p[0] === '') { | ||
// first part is blank: year starts with a minus sign | ||
CE = false; | ||
p.splice(0, 1); | ||
} | ||
|
||
if(p.length > 3 || (p.length !== 3 && datetime[1])) return BADNUM; | ||
|
||
// year | ||
if(p[0].length === 4) y = Number(p[0]); | ||
else if(p[0].length === 2) { | ||
if(!CE) return BADNUM; | ||
var yNow = new Date().getFullYear(); | ||
y = ((Number(p[0]) - yNow + 70) % 100 + 200) % 100 + yNow - 70; | ||
} | ||
else return false; | ||
if(!isNumeric(y)) return false; | ||
if(p.length === 1) return new Date(y, 0, 1).getTime(); // year only | ||
|
||
// month | ||
m = Number(p[1]) - 1; // new Date() uses zero-based months | ||
if(p[1].length > 2 || !(m >= 0 && m <= 11)) return false; | ||
if(p.length === 2) return new Date(y, m, 1).getTime(); // year-month | ||
|
||
// day | ||
d = Number(p[2]); | ||
if(p[2].length > 2 || !(d >= 1 && d <= 31)) return false; | ||
|
||
// now save the date part | ||
d = new Date(y, m, d).getTime(); | ||
if(!datetime[1]) return d; // year-month-day | ||
p = datetime[1].split(':'); | ||
if(p.length > 3) return false; | ||
|
||
// hour | ||
h = Number(p[0]); | ||
if(p[0].length > 2 || !(h >= 0 && h <= 23)) return false; | ||
d += 3600000 * h; | ||
if(p.length === 1) return d; | ||
|
||
// minute | ||
m = Number(p[1]); | ||
if(p[1].length > 2 || !(m >= 0 && m <= 59)) return false; | ||
d += 60000 * m; | ||
if(p.length === 2) return d; | ||
|
||
// second | ||
s = Number(p[2]); | ||
if(!(s >= 0 && s < 60)) return false; | ||
return d + s * 1000; | ||
else return BADNUM; | ||
if(!isNumeric(y)) return BADNUM; | ||
|
||
// javascript takes new Date(0..99,m,d) to mean 1900-1999, so | ||
// to support years 0-99 we need to use setFullYear explicitly | ||
var baseDate = new Date(0, 0, 1); | ||
baseDate.setFullYear(CE ? y : -y); | ||
if(p.length > 1) { | ||
|
||
// month | ||
m = Number(p[1]) - 1; // new Date() uses zero-based months | ||
if(p[1].length > 2 || !(m >= 0 && m <= 11)) return BADNUM; | ||
baseDate.setMonth(m); | ||
|
||
if(p.length > 2) { | ||
|
||
// day | ||
d = Number(p[2]); | ||
if(p[2].length > 2 || !(d >= 1 && d <= 31)) return BADNUM; | ||
baseDate.setDate(d); | ||
|
||
// does that date exist in this month? | ||
if(baseDate.getDate() !== d) return BADNUM; | ||
|
||
if(datetime[1]) { | ||
|
||
p = datetime[1].split(':'); | ||
if(p.length > 3) return BADNUM; | ||
|
||
// hour | ||
h = Number(p[0]); | ||
if(p[0].length > 2 || !(h >= 0 && h <= 23)) return BADNUM; | ||
baseDate.setHours(h); | ||
|
||
// does that hour exist in this day? (Daylight time!) | ||
// (TODO: remove this check when we move to UTC) | ||
if(baseDate.getHours() !== h) return BADNUM; | ||
|
||
if(p.length > 1) { | ||
d = baseDate.getTime(); | ||
|
||
// minute | ||
m = Number(p[1]); | ||
if(p[1].length > 2 || !(m >= 0 && m <= 59)) return BADNUM; | ||
d += 60000 * m; | ||
if(p.length === 2) return d; | ||
|
||
// second (and milliseconds) | ||
s = Number(p[2]); | ||
if(!(s >= 0 && s < 60)) return BADNUM; | ||
return d + s * 1000; | ||
} | ||
} | ||
} | ||
} | ||
return baseDate.getTime(); | ||
}; | ||
|
||
exports.MIN_MS = exports.dateTime2ms('-9999'); | ||
exports.MAX_MS = exports.dateTime2ms('9999'); | ||
|
||
// is string s a date? (see above) | ||
exports.isDateTime = function(s) { | ||
return (exports.dateTime2ms(s) !== false); | ||
return (exports.dateTime2ms(s) !== BADNUM); | ||
}; | ||
|
||
// pad a number with zeroes, to given # of digits before the decimal point | ||
|
@@ -123,6 +162,8 @@ function lpad(val, digits) { | |
exports.ms2DateTime = function(ms, r) { | ||
if(!r) r = 0; | ||
|
||
if(ms < exports.MIN_MS || ms > exports.MAX_MS) return BADNUM; | ||
|
||
var d = new Date(ms), | ||
s = d3.time.format('%Y-%m-%d')(d); | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,8 @@ lib.dateTime2ms = datesModule.dateTime2ms; | |
lib.isDateTime = datesModule.isDateTime; | ||
lib.ms2DateTime = datesModule.ms2DateTime; | ||
lib.parseDate = datesModule.parseDate; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎉 |
||
lib.MIN_MS = datesModule.MIN_MS; | ||
lib.MAX_MS = datesModule.MAX_MS; | ||
|
||
var searchModule = require('./search'); | ||
lib.findBin = searchModule.findBin; | ||
|
@@ -75,6 +77,10 @@ lib.error = loggersModule.error; | |
|
||
lib.notifier = require('./notifier'); | ||
|
||
var constantsModule = require('./constants'); | ||
lib.BADNUM = constantsModule.BADNUM, | ||
lib.FP_SAFE = constantsModule.FP_SAFE; | ||
|
||
/** | ||
* swap x and y of the same attribute in container cont | ||
* specify attr with a ? in place of x/y | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh you added a
src/lib/constants.js
file, there's also asrc/constants/
directory in case you haven't noticed.I'm exactly not sure where to draw the line between the two. Maybe putting this in
src/constants/numerical.js
would be best. But this is non- ⛔ ; I'll let you decide what's best.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah OK - no I hadn't noticed that dir, I'll move it in there. I made the file to get
BADNUM
out ofsrc/plots/cartesian/constants.js
, perhaps eventually this should move there too.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
51a0563