Skip to content

Commit fff9123

Browse files
committed
Add support for parsing weekdays and week numbers.
Also includes support for parsing "%" literals.
1 parent f86be42 commit fff9123

4 files changed

Lines changed: 167 additions & 42 deletions

File tree

d3.js

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8272,7 +8272,10 @@ d3 = function() {
82728272
if (i != string.length) return null;
82738273
if ("p" in d) d.H = d.H % 12 + d.p * 12;
82748274
var date = new d3_time();
8275-
date.setFullYear(d.y, d.m, d.d);
8275+
if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) {
8276+
date.setFullYear(d.y, 0, 1);
8277+
date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7);
8278+
} else date.setFullYear(d.y, d.m, d.d);
82768279
date.setHours(d.H, d.M, d.S, d.L);
82778280
return date;
82788281
};
@@ -8307,7 +8310,7 @@ d3 = function() {
83078310
var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length;
83088311
return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
83098312
}
8310-
var d3_time_dayRe = d3_time_formatRe(d3_time_days), d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), d3_time_monthRe = d3_time_formatRe(d3_time_months), d3_time_monthLookup = d3_time_formatLookup(d3_time_months), d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations);
8313+
var d3_time_dayRe = d3_time_formatRe(d3_time_days), d3_time_dayLookup = d3_time_formatLookup(d3_time_days), d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations), d3_time_dayAbbrevLookup = d3_time_formatLookup(d3_time_dayAbbreviations), d3_time_monthRe = d3_time_formatRe(d3_time_months), d3_time_monthLookup = d3_time_formatLookup(d3_time_months), d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations), d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations), d3_time_percentRe = /^%/;
83118314
var d3_time_formatPads = {
83128315
"-": "",
83138316
_: " ",
@@ -8389,35 +8392,55 @@ d3 = function() {
83898392
e: d3_time_parseDay,
83908393
H: d3_time_parseHour24,
83918394
I: d3_time_parseHour24,
8395+
j: d3_time_parseDayOfYear,
83928396
L: d3_time_parseMilliseconds,
83938397
m: d3_time_parseMonthNumber,
83948398
M: d3_time_parseMinutes,
83958399
p: d3_time_parseAmPm,
83968400
S: d3_time_parseSeconds,
8401+
U: d3_time_parseWeekNumberSunday,
8402+
w: d3_time_parseWeekdayNumber,
8403+
W: d3_time_parseWeekNumberMonday,
83978404
x: d3_time_parseLocaleDate,
83988405
X: d3_time_parseLocaleTime,
83998406
y: d3_time_parseYear,
8400-
Y: d3_time_parseFullYear
8407+
Y: d3_time_parseFullYear,
8408+
"%": d3_time_parseLiteralPercent
84018409
};
84028410
function d3_time_parseWeekdayAbbrev(date, string, i) {
84038411
d3_time_dayAbbrevRe.lastIndex = 0;
84048412
var n = d3_time_dayAbbrevRe.exec(string.substring(i));
8405-
return n ? i += n[0].length : -1;
8413+
return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
84068414
}
84078415
function d3_time_parseWeekday(date, string, i) {
84088416
d3_time_dayRe.lastIndex = 0;
84098417
var n = d3_time_dayRe.exec(string.substring(i));
8410-
return n ? i += n[0].length : -1;
8418+
return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
8419+
}
8420+
function d3_time_parseWeekdayNumber(date, string, i) {
8421+
d3_time_numberRe.lastIndex = 0;
8422+
var n = d3_time_numberRe.exec(string.substring(i, i + 1));
8423+
return n ? (date.w = +n[0], i + n[0].length) : -1;
8424+
}
8425+
function d3_time_parseWeekNumberSunday(date, string, i) {
8426+
d3_time_numberRe.lastIndex = 0;
8427+
var n = d3_time_numberRe.exec(string.substring(i));
8428+
return n ? (date.U = +n[0], i + n[0].length) : -1;
8429+
}
8430+
function d3_time_parseWeekNumberMonday(date, string, i) {
8431+
d3_time_numberRe.lastIndex = 0;
8432+
var n = d3_time_numberRe.exec(string.substring(i));
8433+
return n ? (date.W = +n[0], i + n[0].length) : -1;
84118434
}
84128435
function d3_time_parseMonthAbbrev(date, string, i) {
84138436
d3_time_monthAbbrevRe.lastIndex = 0;
84148437
var n = d3_time_monthAbbrevRe.exec(string.substring(i));
8415-
return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
8438+
return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
84168439
}
84178440
function d3_time_parseMonth(date, string, i) {
84188441
d3_time_monthRe.lastIndex = 0;
84198442
var n = d3_time_monthRe.exec(string.substring(i));
8420-
return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
8443+
return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
84218444
}
84228445
function d3_time_parseLocaleFull(date, string, i) {
84238446
return d3_time_parse(date, d3_time_formats.c.toString(), string, i);
@@ -8431,45 +8454,50 @@ d3 = function() {
84318454
function d3_time_parseFullYear(date, string, i) {
84328455
d3_time_numberRe.lastIndex = 0;
84338456
var n = d3_time_numberRe.exec(string.substring(i, i + 4));
8434-
return n ? (date.y = +n[0], i += n[0].length) : -1;
8457+
return n ? (date.y = +n[0], i + n[0].length) : -1;
84358458
}
84368459
function d3_time_parseYear(date, string, i) {
84378460
d3_time_numberRe.lastIndex = 0;
84388461
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8439-
return n ? (date.y = d3_time_expandYear(+n[0]), i += n[0].length) : -1;
8462+
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
84408463
}
84418464
function d3_time_expandYear(d) {
84428465
return d + (d > 68 ? 1900 : 2e3);
84438466
}
84448467
function d3_time_parseMonthNumber(date, string, i) {
84458468
d3_time_numberRe.lastIndex = 0;
84468469
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8447-
return n ? (date.m = n[0] - 1, i += n[0].length) : -1;
8470+
return n ? (date.m = n[0] - 1, i + n[0].length) : -1;
84488471
}
84498472
function d3_time_parseDay(date, string, i) {
84508473
d3_time_numberRe.lastIndex = 0;
84518474
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8452-
return n ? (date.d = +n[0], i += n[0].length) : -1;
8475+
return n ? (date.d = +n[0], i + n[0].length) : -1;
8476+
}
8477+
function d3_time_parseDayOfYear(date, string, i) {
8478+
d3_time_numberRe.lastIndex = 0;
8479+
var n = d3_time_numberRe.exec(string.substring(i, i + 3));
8480+
return n ? (date.j = +n[0], i + n[0].length) : -1;
84538481
}
84548482
function d3_time_parseHour24(date, string, i) {
84558483
d3_time_numberRe.lastIndex = 0;
84568484
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8457-
return n ? (date.H = +n[0], i += n[0].length) : -1;
8485+
return n ? (date.H = +n[0], i + n[0].length) : -1;
84588486
}
84598487
function d3_time_parseMinutes(date, string, i) {
84608488
d3_time_numberRe.lastIndex = 0;
84618489
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8462-
return n ? (date.M = +n[0], i += n[0].length) : -1;
8490+
return n ? (date.M = +n[0], i + n[0].length) : -1;
84638491
}
84648492
function d3_time_parseSeconds(date, string, i) {
84658493
d3_time_numberRe.lastIndex = 0;
84668494
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
8467-
return n ? (date.S = +n[0], i += n[0].length) : -1;
8495+
return n ? (date.S = +n[0], i + n[0].length) : -1;
84688496
}
84698497
function d3_time_parseMilliseconds(date, string, i) {
84708498
d3_time_numberRe.lastIndex = 0;
84718499
var n = d3_time_numberRe.exec(string.substring(i, i + 3));
8472-
return n ? (date.L = +n[0], i += n[0].length) : -1;
8500+
return n ? (date.L = +n[0], i + n[0].length) : -1;
84738501
}
84748502
var d3_time_numberRe = /^\s*\d+/;
84758503
function d3_time_parseAmPm(date, string, i) {
@@ -8484,6 +8512,11 @@ d3 = function() {
84848512
var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60;
84858513
return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2);
84868514
}
8515+
function d3_time_parseLiteralPercent(date, string, i) {
8516+
d3_time_percentRe.lastIndex = 0;
8517+
var n = d3_time_percentRe.exec(string.substring(i, i + 1));
8518+
return n ? i + n[0].length : -1;
8519+
}
84878520
d3.time.format.utc = function(template) {
84888521
var local = d3.time.format(template);
84898522
function format(date) {

d3.min.js

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/time/format.js

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,14 @@ d3.time.format = function(template) {
3636
// The am-pm flag is 0 for AM, and 1 for PM.
3737
if ("p" in d) d.H = d.H % 12 + d.p * 12;
3838

39-
var date = new d3_time();
40-
date.setFullYear(d.y, d.m, d.d);
39+
var date = new d3_time;
40+
if ("j" in d) date.setFullYear(d.y, 0, d.j);
41+
else if ("w" in d && ("W" in d || "U" in d)) {
42+
date.setFullYear(d.y, 0, 1);
43+
date.setFullYear(d.y, 0, "W" in d
44+
? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7
45+
: d.w + d.U * 7 - (date.getDay() + 6) % 7);
46+
} else date.setFullYear(d.y, d.m, d.d);
4147
date.setHours(d.H, d.M, d.S, d.L);
4248
return date;
4349
};
@@ -86,11 +92,14 @@ function d3_time_formatPad(value, fill, width) {
8692
}
8793

8894
var d3_time_dayRe = d3_time_formatRe(d3_time_days),
95+
d3_time_dayLookup = d3_time_formatLookup(d3_time_days),
8996
d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations),
97+
d3_time_dayAbbrevLookup = d3_time_formatLookup(d3_time_dayAbbreviations),
9098
d3_time_monthRe = d3_time_formatRe(d3_time_months),
9199
d3_time_monthLookup = d3_time_formatLookup(d3_time_months),
92100
d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations),
93-
d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations);
101+
d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations),
102+
d3_time_percentRe = /^%/;
94103

95104
var d3_time_formatPads = {
96105
"-": "",
@@ -135,48 +144,65 @@ var d3_time_parsers = {
135144
e: d3_time_parseDay,
136145
H: d3_time_parseHour24,
137146
I: d3_time_parseHour24,
138-
// j: function(d, s, i) { /*TODO day of year [001,366] */ return i; },
147+
j: d3_time_parseDayOfYear,
139148
L: d3_time_parseMilliseconds,
140149
m: d3_time_parseMonthNumber,
141150
M: d3_time_parseMinutes,
142151
p: d3_time_parseAmPm,
143152
S: d3_time_parseSeconds,
144-
// U: function(d, s, i) { /*TODO week number (sunday) [00,53] */ return i; },
145-
// w: function(d, s, i) { /*TODO weekday [0,6] */ return i; },
146-
// W: function(d, s, i) { /*TODO week number (monday) [00,53] */ return i; },
153+
U: d3_time_parseWeekNumberSunday,
154+
w: d3_time_parseWeekdayNumber,
155+
W: d3_time_parseWeekNumberMonday,
147156
x: d3_time_parseLocaleDate,
148157
X: d3_time_parseLocaleTime,
149158
y: d3_time_parseYear,
150-
Y: d3_time_parseFullYear
151-
// ,
159+
Y: d3_time_parseFullYear,
152160
// Z: function(d, s, i) { /*TODO time zone */ return i; },
153-
// "%": function(d, s, i) { /*TODO literal % */ return i; }
161+
"%": d3_time_parseLiteralPercent
154162
};
155163

156164
// Note: weekday is validated, but does not set the date.
157165
function d3_time_parseWeekdayAbbrev(date, string, i) {
158166
d3_time_dayAbbrevRe.lastIndex = 0;
159167
var n = d3_time_dayAbbrevRe.exec(string.substring(i));
160-
return n ? i += n[0].length : -1;
168+
return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
161169
}
162170

163171
// Note: weekday is validated, but does not set the date.
164172
function d3_time_parseWeekday(date, string, i) {
165173
d3_time_dayRe.lastIndex = 0;
166174
var n = d3_time_dayRe.exec(string.substring(i));
167-
return n ? i += n[0].length : -1;
175+
return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
176+
}
177+
178+
function d3_time_parseWeekdayNumber(date, string, i) {
179+
d3_time_numberRe.lastIndex = 0;
180+
var n = d3_time_numberRe.exec(string.substring(i, i + 1));
181+
return n ? (date.w = +n[0], i + n[0].length) : -1;
182+
}
183+
184+
function d3_time_parseWeekNumberSunday(date, string, i) {
185+
d3_time_numberRe.lastIndex = 0;
186+
var n = d3_time_numberRe.exec(string.substring(i));
187+
return n ? (date.U = +n[0], i + n[0].length) : -1;
188+
}
189+
190+
function d3_time_parseWeekNumberMonday(date, string, i) {
191+
d3_time_numberRe.lastIndex = 0;
192+
var n = d3_time_numberRe.exec(string.substring(i));
193+
return n ? (date.W = +n[0], i + n[0].length) : -1;
168194
}
169195

170196
function d3_time_parseMonthAbbrev(date, string, i) {
171197
d3_time_monthAbbrevRe.lastIndex = 0;
172198
var n = d3_time_monthAbbrevRe.exec(string.substring(i));
173-
return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
199+
return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
174200
}
175201

176202
function d3_time_parseMonth(date, string, i) {
177203
d3_time_monthRe.lastIndex = 0;
178204
var n = d3_time_monthRe.exec(string.substring(i));
179-
return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i += n[0].length) : -1;
205+
return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
180206
}
181207

182208
function d3_time_parseLocaleFull(date, string, i) {
@@ -194,13 +220,13 @@ function d3_time_parseLocaleTime(date, string, i) {
194220
function d3_time_parseFullYear(date, string, i) {
195221
d3_time_numberRe.lastIndex = 0;
196222
var n = d3_time_numberRe.exec(string.substring(i, i + 4));
197-
return n ? (date.y = +n[0], i += n[0].length) : -1;
223+
return n ? (date.y = +n[0], i + n[0].length) : -1;
198224
}
199225

200226
function d3_time_parseYear(date, string, i) {
201227
d3_time_numberRe.lastIndex = 0;
202228
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
203-
return n ? (date.y = d3_time_expandYear(+n[0]), i += n[0].length) : -1;
229+
return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1;
204230
}
205231

206232
function d3_time_expandYear(d) {
@@ -210,38 +236,44 @@ function d3_time_expandYear(d) {
210236
function d3_time_parseMonthNumber(date, string, i) {
211237
d3_time_numberRe.lastIndex = 0;
212238
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
213-
return n ? (date.m = n[0] - 1, i += n[0].length) : -1;
239+
return n ? (date.m = n[0] - 1, i + n[0].length) : -1;
214240
}
215241

216242
function d3_time_parseDay(date, string, i) {
217243
d3_time_numberRe.lastIndex = 0;
218244
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
219-
return n ? (date.d = +n[0], i += n[0].length) : -1;
245+
return n ? (date.d = +n[0], i + n[0].length) : -1;
246+
}
247+
248+
function d3_time_parseDayOfYear(date, string, i) {
249+
d3_time_numberRe.lastIndex = 0;
250+
var n = d3_time_numberRe.exec(string.substring(i, i + 3));
251+
return n ? (date.j = +n[0], i + n[0].length) : -1;
220252
}
221253

222254
// Note: we don't validate that the hour is in the range [0,23] or [1,12].
223255
function d3_time_parseHour24(date, string, i) {
224256
d3_time_numberRe.lastIndex = 0;
225257
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
226-
return n ? (date.H = +n[0], i += n[0].length) : -1;
258+
return n ? (date.H = +n[0], i + n[0].length) : -1;
227259
}
228260

229261
function d3_time_parseMinutes(date, string, i) {
230262
d3_time_numberRe.lastIndex = 0;
231263
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
232-
return n ? (date.M = +n[0], i += n[0].length) : -1;
264+
return n ? (date.M = +n[0], i + n[0].length) : -1;
233265
}
234266

235267
function d3_time_parseSeconds(date, string, i) {
236268
d3_time_numberRe.lastIndex = 0;
237269
var n = d3_time_numberRe.exec(string.substring(i, i + 2));
238-
return n ? (date.S = +n[0], i += n[0].length) : -1;
270+
return n ? (date.S = +n[0], i + n[0].length) : -1;
239271
}
240272

241273
function d3_time_parseMilliseconds(date, string, i) {
242274
d3_time_numberRe.lastIndex = 0;
243275
var n = d3_time_numberRe.exec(string.substring(i, i + 3));
244-
return n ? (date.L = +n[0], i += n[0].length) : -1;
276+
return n ? (date.L = +n[0], i + n[0].length) : -1;
245277
}
246278

247279
// Note: we don't look at the next directive.
@@ -265,3 +297,9 @@ function d3_time_zone(d) {
265297
zm = Math.abs(z) % 60;
266298
return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2);
267299
}
300+
301+
function d3_time_parseLiteralPercent(date, string, i) {
302+
d3_time_percentRe.lastIndex = 0;
303+
var n = d3_time_percentRe.exec(string.substring(i, i + 1));
304+
return n ? i + n[0].length : -1;
305+
}

0 commit comments

Comments
 (0)