-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
World calendars #1220
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
World calendars #1220
Changes from 1 commit
d2a5e4b
6151575
4b9edec
4d8f79a
84a51c2
13cf6b1
165125b
86b31ea
78b6646
1b563f5
4e9a632
c1c24e8
a435981
6653da7
8e1747f
00ae2dd
3143099
5984106
03ab34f
db3d18b
05b2f96
61ecd42
68af287
cb2c54b
bc457a9
1444f55
08f18ca
dcddcee
bbb76a4
8d8e936
0e05f95
509f287
7bd501f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,6 +41,7 @@ var handleTraceDefaults = function(traceIn, traceOut, coords, layout) { | |
// all support either of those dates. Instead I'll use the most significant | ||
// number they *do* support, biased toward the present day. | ||
var CANONICAL_TICK = { | ||
chinese: '2000-01-01', | ||
coptic: '2000-01-01', | ||
discworld: '2000-01-01', | ||
ethiopian: '2000-01-01', | ||
|
@@ -58,11 +59,13 @@ var CANONICAL_TICK = { | |
}; | ||
|
||
// Start on a Sunday - for week ticks | ||
// Discworld and Mayan calendars don't have 7-day weeks anyway so don't change them. | ||
// Discworld and Mayan calendars don't have 7-day weeks but we're going to give them | ||
// 7-day week ticks so start on our Sundays. | ||
// If anyone really cares we can customize the auto tick spacings for these calendars. | ||
var CANONICAL_SUNDAY = { | ||
chinese: '2000-01-02', | ||
coptic: '2000-01-03', | ||
discworld: '2000-01-01', | ||
discworld: '2000-01-03', | ||
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. bug fix or typo? 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. see the comment change above - I decided it would be better to keep our Sundays unless and until we support the native weeks in these calendars. |
||
ethiopian: '2000-01-05', | ||
hebrew: '5000-01-01', | ||
islamic: '1000-01-02', | ||
|
@@ -78,6 +81,7 @@ var CANONICAL_SUNDAY = { | |
}; | ||
|
||
var DFLTRANGE = { | ||
chinese: ['2000-01-01', '2001-01-01'], | ||
coptic: ['1700-01-01', '1701-01-01'], | ||
discworld: ['1800-01-01', '1801-01-01'], | ||
ethiopian: ['2000-01-01', '2001-01-01'], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,8 @@ var Registry = require('../registry'); | |
var utcFormat = d3.time.format.utc; | ||
|
||
var DATETIME_REGEXP = /^\s*(-?\d\d\d\d|\d\d)(-(\d?\d)(-(\d?\d)([ Tt]([01]?\d|2[0-3])(:([0-5]\d)(:([0-5]\d(\.\d+)?))?(Z|z|[+\-]\d\d:?\d\d)?)?)?)?)?\s*$/m; | ||
// special regex for chinese calendars to support yyyy-mmi-dd etc for intercalary months | ||
var DATETIME_REGEXP_CN = /^\s*(-?\d\d\d\d|\d\d)(-(\d?\di?)(-(\d?\d)([ Tt]([01]?\d|2[0-3])(:([0-5]\d)(:([0-5]\d(\.\d+)?))?(Z|z|[+\-]\d\d:?\d\d)?)?)?)?)?\s*$/m; | ||
|
||
// for 2-digit years, the first year we map them onto | ||
var YFIRST = new Date().getFullYear() - 70; | ||
|
@@ -155,10 +157,12 @@ exports.dateTime2ms = function(s, calendar) { | |
calendar = ''; | ||
} | ||
|
||
var match = s.match(DATETIME_REGEXP); | ||
var isChinese = calendar && calendar.substr(0, 7) === 'chinese'; | ||
|
||
var match = s.match(isChinese ? DATETIME_REGEXP_CN : DATETIME_REGEXP); | ||
if(!match) return BADNUM; | ||
var y = match[1], | ||
m = Number(match[3] || 1), | ||
m = match[3] || '1', | ||
d = Number(match[5] || 1), | ||
H = Number(match[7] || 0), | ||
M = Number(match[9] || 0), | ||
|
@@ -167,11 +171,19 @@ exports.dateTime2ms = function(s, calendar) { | |
if(isWorld) { | ||
// disallow 2-digit years for world calendars | ||
if(y.length === 2) return BADNUM; | ||
y = Number(y); | ||
|
||
var cDate; | ||
try { | ||
cDate = Registry.getComponentMethod('calendars', 'getCal')(calendar) | ||
.newDate(Number(y), m, d); | ||
var calInstance = Registry.getComponentMethod('calendars', 'getCal')(calendar); | ||
if(isChinese) { | ||
var isIntercalary = m.charAt(m.length - 1) === 'i'; | ||
m = Number(isIntercalary ? m.substr(0, m.length - 1) : m); | ||
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. I think 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. ah good call - I always forget about parseInt. |
||
cDate = calInstance.newDate(y, calInstance.toMonthIndex(y, m, isIntercalary), d); | ||
} | ||
else { | ||
cDate = calInstance.newDate(y, Number(m), d); | ||
} | ||
} | ||
catch(e) { return BADNUM; } // Invalid ... date | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
var isNumeric = require('fast-isnumeric'); | ||
|
||
var Lib = require('@src/lib'); | ||
var calComponent = require('@src/components/calendars'); | ||
|
||
// use only the parts of world-calendars that we've imported for our tests | ||
var calendars = require('@src/components/calendars/calendars'); | ||
|
||
describe('dates', function() { | ||
'use strict'; | ||
|
@@ -240,6 +245,7 @@ describe('dates', function() { | |
[ | ||
[undefined, '1970-01-01'], | ||
['gregorian', '1970-01-01'], | ||
['chinese', '1969-11-24'], | ||
['coptic', '1686-04-23'], | ||
['discworld', '1798-12-27'], | ||
['ethiopian', '1962-04-23'], | ||
|
@@ -284,6 +290,55 @@ describe('dates', function() { | |
expect(Lib.dateTime2ms(expected_lastinstant, calendar)).toBe(lastInstant, calendar); | ||
}); | ||
}); | ||
|
||
it('should contain canonical ticks sundays, ranges for all calendars', function() { | ||
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 test 🍻 |
||
var calList = Object.keys(calendars.calendars).filter(function(v) { | ||
return v !== 'gregorian'; | ||
}); | ||
|
||
var canonicalTick = calComponent.CANONICAL_TICK, | ||
canonicalSunday = calComponent.CANONICAL_SUNDAY, | ||
dfltRange = calComponent.DFLTRANGE; | ||
expect(Object.keys(canonicalTick).length).toBe(calList.length); | ||
expect(Object.keys(canonicalSunday).length).toBe(calList.length); | ||
expect(Object.keys(dfltRange).length).toBe(calList.length); | ||
|
||
calList.forEach(function(calendar) { | ||
expect(Lib.dateTime2ms(canonicalTick[calendar], calendar)).toBeDefined(calendar); | ||
var sunday = Lib.dateTime2ms(canonicalSunday[calendar], calendar); | ||
// convert back implicitly with gregorian calendar | ||
expect(Lib.formatDate(sunday, '%A')).toBe('Sunday', calendar); | ||
|
||
expect(Lib.dateTime2ms(dfltRange[calendar][0], calendar)).toBeDefined(calendar); | ||
expect(Lib.dateTime2ms(dfltRange[calendar][1], calendar)).toBeDefined(calendar); | ||
}); | ||
}); | ||
|
||
it('should handle Chinese intercalary months correctly', function() { | ||
var intercalaryDates = [ | ||
'1995-08i-01', | ||
'1995-08i-29', | ||
'1984-10i-15', | ||
'2023-02i-29' | ||
]; | ||
intercalaryDates.forEach(function(v) { | ||
var ms = Lib.dateTime2ms(v, 'chinese'); | ||
expect(Lib.ms2DateTime(ms, 0, 'chinese')).toBe(v); | ||
|
||
// should also work without leading zeros | ||
var vShort = v.replace(/-0/g, '-'); | ||
expect(Lib.dateTime2ms(vShort, 'chinese')).toBe(ms, vShort); | ||
}); | ||
|
||
var badIntercalaryDates = [ | ||
'1995-07i-01', | ||
'1995-08i-30', | ||
'1995-09i-01' | ||
]; | ||
badIntercalaryDates.forEach(function(v) { | ||
expect(Lib.dateTime2ms(v, 'chinese')).toBeUndefined(v); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('cleanDate', function() { | ||
|
@@ -341,6 +396,51 @@ describe('dates', function() { | |
}); | ||
}); | ||
|
||
describe('incrementMonth', function() { | ||
it('should include Chinese intercalary months', function() { | ||
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. I should add a similar tests to world-calendars |
||
var start = '1995-06-01'; | ||
var expected = [ | ||
'1995-07-01', | ||
'1995-08-01', | ||
'1995-08i-01', | ||
'1995-09-01', | ||
'1995-10-01', | ||
'1995-11-01', | ||
'1995-12-01', | ||
'1996-01-01' | ||
]; | ||
var tick = Lib.dateTime2ms(start, 'chinese'); | ||
expected.forEach(function(v) { | ||
tick = Lib.incrementMonth(tick, 1, 'chinese'); | ||
expect(tick).toBe(Lib.dateTime2ms(v, 'chinese'), v); | ||
}); | ||
}); | ||
|
||
it('should increment years even over leap years', function() { | ||
var start = '1995-06-01'; | ||
var expected = [ | ||
'1996-06-01', | ||
'1997-06-01', | ||
'1998-06-01', | ||
'1999-06-01', | ||
'2000-06-01', | ||
'2001-06-01', | ||
'2002-06-01', | ||
'2003-06-01', | ||
'2004-06-01', | ||
'2005-06-01', | ||
'2006-06-01', | ||
'2007-06-01', | ||
'2008-06-01' | ||
]; | ||
var tick = Lib.dateTime2ms(start, 'chinese'); | ||
expected.forEach(function(v) { | ||
tick = Lib.incrementMonth(tick, 12, 'chinese'); | ||
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. 12? I guess 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. yes exactly: #1220 (comment) |
||
expect(tick).toBe(Lib.dateTime2ms(v, 'chinese'), v); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('isJSDate', function() { | ||
it('should return true for any Date object but not the equivalent numbers', function() { | ||
[ | ||
|
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.
🍻