Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3143099

Browse files
committed
move world-calendar logic in lib/dates.js to new 'calendars' component
- use Registry in lib.dates.js to invoke world-calendar logic on-demand.
1 parent 00ae2dd commit 3143099

File tree

3 files changed

+201
-149
lines changed

3 files changed

+201
-149
lines changed

src/components/calendars/index.js

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/**
2+
* Copyright 2012-2016, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
'use strict';
10+
11+
var calendars = require('world-calendars');
12+
13+
var Lib = require('../../lib');
14+
var constants = require('../../constants/numerical');
15+
16+
var EPOCHJD = constants.EPOCHJD;
17+
var ONEDAY = constants.ONEDAY;
18+
19+
// each calendar needs its own default canonical tick. I would love to use
20+
// 2000-01-01 (or even 0000-01-01) for them all but they don't necessarily
21+
// all support either of those dates. Instead I'll use the most significant
22+
// number they *do* support, biased toward the present day.
23+
var CANONICAL_TICK = {
24+
coptic: '2000-01-01',
25+
discworld: '2000-01-01',
26+
ethiopian: '2000-01-01',
27+
hebrew: '5000-01-01',
28+
islamic: '1000-01-01',
29+
julian: '2000-01-01',
30+
mayan: '5000-01-01',
31+
nanakshahi: '1000-01-01',
32+
nepali: '2000-01-01',
33+
persian: '1000-01-01',
34+
jalali: '1000-01-01',
35+
taiwan: '1000-01-01',
36+
thai: '2000-01-01',
37+
ummalqura: '1400-01-01'
38+
};
39+
40+
// Start on a Sunday - for week ticks
41+
// Discworld and Mayan calendars don't have 7-day weeks anyway so don't change them.
42+
// If anyone really cares we can customize the auto tick spacings for these calendars.
43+
var CANONICAL_SUNDAY = {
44+
coptic: '2000-01-03',
45+
discworld: '2000-01-01',
46+
ethiopian: '2000-01-05',
47+
hebrew: '5000-01-01',
48+
islamic: '1000-01-02',
49+
julian: '2000-01-03',
50+
mayan: '5000-01-01',
51+
nanakshahi: '1000-01-05',
52+
nepali: '2000-01-05',
53+
persian: '1000-01-01',
54+
jalali: '1000-01-01',
55+
taiwan: '1000-01-04',
56+
thai: '2000-01-04',
57+
ummalqura: '1400-01-06'
58+
};
59+
60+
var DFLTRANGE = {
61+
coptic: ['1700-01-01', '1701-01-01'],
62+
discworld: ['1800-01-01', '1801-01-01'],
63+
ethiopian: ['2000-01-01', '2001-01-01'],
64+
hebrew: ['5700-01-01', '5701-01-01'],
65+
islamic: ['1400-01-01', '1401-01-01'],
66+
julian: ['2000-01-01', '2001-01-01'],
67+
mayan: ['5200-01-01', '5201-01-01'],
68+
nanakshahi: ['0500-01-01', '0501-01-01'],
69+
nepali: ['2000-01-01', '2001-01-01'],
70+
persian: ['1400-01-01', '1401-01-01'],
71+
jalali: ['1400-01-01', '1401-01-01'],
72+
taiwan: ['0100-01-01', '0101-01-01'],
73+
thai: ['2500-01-01', '2501-01-01'],
74+
ummalqura: ['1400-01-01', '1401-01-01']
75+
};
76+
77+
/*
78+
* convert d3 templates to world-calendars templates, so our users only need
79+
* to know d3's specifiers. Map space padding to no padding, and unknown fields
80+
* to an ugly placeholder
81+
*/
82+
var UNKNOWN = '##';
83+
var d3ToWorldCalendars = {
84+
'd': {'0': 'dd', '-': 'd'}, // 2-digit or unpadded day of month
85+
'a': {'0': 'D', '-': 'D'}, // short weekday name
86+
'A': {'0': 'DD', '-': 'DD'}, // full weekday name
87+
'j': {'0': 'oo', '-': 'o'}, // 3-digit or unpadded day of the year
88+
'W': {'0': 'ww', '-': 'w'}, // 2-digit or unpadded week of the year (Monday first)
89+
'm': {'0': 'mm', '-': 'm'}, // 2-digit or unpadded month number
90+
'b': {'0': 'M', '-': 'M'}, // short month name
91+
'B': {'0': 'MM', '-': 'MM'}, // full month name
92+
'y': {'0': 'yy', '-': 'yy'}, // 2-digit year (map unpadded to zero-padded)
93+
'Y': {'0': 'yyyy', '-': 'yyyy'}, // 4-digit year (map unpadded to zero-padded)
94+
'U': UNKNOWN, // Sunday-first week of the year
95+
'w': UNKNOWN, // day of the week [0(sunday),6]
96+
// combined format, we replace the date part with the world-calendar version
97+
// and the %X stays there for d3 to handle with time parts
98+
'%c': {'0': 'D M m %X yyyy', '-': 'D M m %X yyyy'},
99+
'%x': {'0': 'mm/dd/yyyy', '-': 'mm/dd/yyyy'}
100+
};
101+
102+
function worldCalFmt(fmt, x, calendar) {
103+
var dateJD = Math.floor(x + 0.05 / ONEDAY) + EPOCHJD,
104+
cDate = getCal(calendar).fromJD(dateJD),
105+
i = 0,
106+
modifier, directive, directiveLen, directiveObj, replacementPart;
107+
while((i = fmt.indexOf('%', i)) !== -1) {
108+
modifier = fmt.charAt(i + 1);
109+
if(modifier === '0' || modifier === '-' || modifier === '_') {
110+
directiveLen = 3;
111+
directive = fmt.charAt(i + 1);
112+
if(modifier === '_') modifier = '-';
113+
}
114+
else {
115+
directive = modifier;
116+
modifier = '0';
117+
directiveLen = 2;
118+
}
119+
directiveObj = d3ToWorldCalendars[directive];
120+
if(!directiveObj) {
121+
i += directiveLen;
122+
}
123+
else {
124+
// code is recognized as a date part but world-calendars doesn't support it
125+
if(directiveObj === UNKNOWN) replacementPart = UNKNOWN;
126+
127+
// format the cDate according to the translated directive
128+
else replacementPart = cDate.formatDate(directiveObj[modifier]);
129+
130+
fmt = fmt.substr(0, i) + replacementPart + fmt.substr(i + directiveLen);
131+
i += replacementPart.length;
132+
}
133+
}
134+
return fmt;
135+
}
136+
137+
// cache world calendars, so we don't have to reinstantiate
138+
// during each date-time conversion
139+
var allCals = {};
140+
function getCal(calendar) {
141+
var calendarObj = allCals[calendar];
142+
if(calendarObj) return calendarObj;
143+
144+
calendarObj = allCals[calendar] = calendars.instance(calendar);
145+
return calendarObj;
146+
}
147+
148+
module.exports = {
149+
moduleType: 'component',
150+
name: 'calendars',
151+
152+
CANONICAL_SUNDAY: CANONICAL_SUNDAY,
153+
CANONICAL_TICK: CANONICAL_TICK,
154+
DFLTRANGE: DFLTRANGE,
155+
156+
getCal: getCal,
157+
worldCalFmt: worldCalFmt
158+
};

src/constants/numerical.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,11 @@ module.exports = {
3636
ONEDAY: 86400000,
3737
ONEHOUR: 3600000,
3838
ONEMIN: 60000,
39-
ONESEC: 1000
39+
ONESEC: 1000,
40+
41+
/*
42+
* For fast conversion btwn world calendars and epoch ms, the Julian Day Number
43+
* of the unix epoch. From calendars.instance().newDate(1970, 1, 1).toJD()
44+
*/
45+
EPOCHJD: 2440587.5
4046
};

0 commit comments

Comments
 (0)