Skip to content

Commit 835c3e1

Browse files
committed
Add support for 0, - and _ fill padding.
For example, "%-d" formats the day with no padding, "%_d" formats the day with space-padding equivalent to "%e", and "%0d" formats the day with zero-padding equivalent to "%d".
1 parent 5cacd70 commit 835c3e1

4 files changed

Lines changed: 95 additions & 60 deletions

File tree

d3.js

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2747,7 +2747,7 @@
27472747
while (i < n) {
27482748
if (j >= m) return -1;
27492749
c = template.charCodeAt(i++);
2750-
if (c == 37) {
2750+
if (c === 37) {
27512751
p = d3_time_parsers[template.charAt(i++)];
27522752
if (!p || (j = p(date, string, j)) < 0) return -1;
27532753
} else if (c != string.charCodeAt(j++)) {
@@ -2764,6 +2764,11 @@
27642764
while (++i < n) map.set(names[i].toLowerCase(), i);
27652765
return map;
27662766
}
2767+
function d3_time_formatPad(value, fill, width) {
2768+
value += "";
2769+
var length = value.length;
2770+
return length < width ? (new Array(width - length + 1)).join(fill) + value : value;
2771+
}
27672772
function d3_time_parseWeekdayAbbrev(date, string, i) {
27682773
d3_time_dayAbbrevRe.lastIndex = 0;
27692774
var n = d3_time_dayAbbrevRe.exec(string.substring(i));
@@ -2842,7 +2847,7 @@
28422847
}
28432848
function d3_time_zone(d) {
28442849
var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(Math.abs(z) / 60), zm = Math.abs(z) % 60;
2845-
return zs + d3_time_zfill2(zh) + d3_time_zfill2(zm);
2850+
return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2);
28462851
}
28472852
function d3_time_formatIsoNative(date) {
28482853
return date.toISOString();
@@ -7250,10 +7255,13 @@
72507255
var d3_time_days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], d3_time_dayAbbreviations = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], d3_time_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], d3_time_monthAbbreviations = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
72517256
d3.time.format = function(template) {
72527257
function format(date) {
7253-
var string = [], i = -1, j = 0, c, f;
7258+
var string = [], i = -1, j = 0, c, p, f;
72547259
while (++i < n) {
7255-
if (template.charCodeAt(i) == 37) {
7256-
string.push(template.substring(j, i), (f = d3_time_formats[c = template.charAt(++i)]) ? f(date) : c);
7260+
if (template.charCodeAt(i) === 37) {
7261+
string.push(template.substring(j, i));
7262+
if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i);
7263+
if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p);
7264+
string.push(c);
72577265
j = i + 1;
72587266
}
72597267
}
@@ -7283,8 +7291,12 @@
72837291
};
72847292
return format;
72857293
};
7286-
var d3_time_zfill2 = d3.format("02d"), d3_time_zfill3 = d3.format("03d"), d3_time_zfill4 = d3.format("04d"), d3_time_sfill2 = d3.format("2d");
72877294
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);
7295+
var d3_time_formatPads = {
7296+
"-": "",
7297+
_: " ",
7298+
"0": "0"
7299+
};
72887300
var d3_time_formats = {
72897301
a: function(d) {
72907302
return d3_time_dayAbbreviations[d.getDay()];
@@ -7299,52 +7311,52 @@
72997311
return d3_time_months[d.getMonth()];
73007312
},
73017313
c: d3.time.format(d3_time_formatDateTime),
7302-
d: function(d) {
7303-
return d3_time_zfill2(d.getDate());
7314+
d: function(d, p) {
7315+
return d3_time_formatPad(d.getDate(), p, 2);
73047316
},
7305-
e: function(d) {
7306-
return d3_time_sfill2(d.getDate());
7317+
e: function(d, p) {
7318+
return d3_time_formatPad(d.getDate(), p, 2);
73077319
},
7308-
H: function(d) {
7309-
return d3_time_zfill2(d.getHours());
7320+
H: function(d, p) {
7321+
return d3_time_formatPad(d.getHours(), p, 2);
73107322
},
7311-
I: function(d) {
7312-
return d3_time_zfill2(d.getHours() % 12 || 12);
7323+
I: function(d, p) {
7324+
return d3_time_formatPad(d.getHours() % 12 || 12, p, 2);
73137325
},
7314-
j: function(d) {
7315-
return d3_time_zfill3(1 + d3.time.dayOfYear(d));
7326+
j: function(d, p) {
7327+
return d3_time_formatPad(1 + d3.time.dayOfYear(d), p, 3);
73167328
},
7317-
L: function(d) {
7318-
return d3_time_zfill3(d.getMilliseconds());
7329+
L: function(d, p) {
7330+
return d3_time_formatPad(d.getMilliseconds(), p, 3);
73197331
},
7320-
m: function(d) {
7321-
return d3_time_zfill2(d.getMonth() + 1);
7332+
m: function(d, p) {
7333+
return d3_time_formatPad(d.getMonth() + 1, p, 2);
73227334
},
7323-
M: function(d) {
7324-
return d3_time_zfill2(d.getMinutes());
7335+
M: function(d, p) {
7336+
return d3_time_formatPad(d.getMinutes(), p, 2);
73257337
},
73267338
p: function(d) {
73277339
return d.getHours() >= 12 ? "PM" : "AM";
73287340
},
7329-
S: function(d) {
7330-
return d3_time_zfill2(d.getSeconds());
7341+
S: function(d, p) {
7342+
return d3_time_formatPad(d.getSeconds(), p, 2);
73317343
},
7332-
U: function(d) {
7333-
return d3_time_zfill2(d3.time.sundayOfYear(d));
7344+
U: function(d, p) {
7345+
return d3_time_formatPad(d3.time.sundayOfYear(d), p, 2);
73347346
},
73357347
w: function(d) {
73367348
return d.getDay();
73377349
},
7338-
W: function(d) {
7339-
return d3_time_zfill2(d3.time.mondayOfYear(d));
7350+
W: function(d, p) {
7351+
return d3_time_formatPad(d3.time.mondayOfYear(d), p, 2);
73407352
},
73417353
x: d3.time.format(d3_time_formatDate),
73427354
X: d3.time.format(d3_time_formatTime),
7343-
y: function(d) {
7344-
return d3_time_zfill2(d.getFullYear() % 100);
7355+
y: function(d, p) {
7356+
return d3_time_formatPad(d.getFullYear() % 100, p, 2);
73457357
},
7346-
Y: function(d) {
7347-
return d3_time_zfill4(d.getFullYear() % 1e4);
7358+
Y: function(d, p) {
7359+
return d3_time_formatPad(d.getFullYear() % 1e4, p, 4);
73487360
},
73497361
Z: d3_time_zone,
73507362
"%": function(d) {

d3.min.js

Lines changed: 4 additions & 4 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: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@ d3.time.format = function(template) {
66
i = -1,
77
j = 0,
88
c,
9+
p,
910
f;
1011
while (++i < n) {
11-
if (template.charCodeAt(i) == 37) {
12-
string.push(
13-
template.substring(j, i),
14-
(f = d3_time_formats[c = template.charAt(++i)])
15-
? f(date) : c);
12+
if (template.charCodeAt(i) === 37) {
13+
string.push(template.substring(j, i));
14+
if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i);
15+
if (f = d3_time_formats[c]) c = f(date, p == null ? (c === "e" ? " " : "0") : p);
16+
string.push(c);
1617
j = i + 1;
1718
}
1819
}
@@ -50,7 +51,7 @@ function d3_time_parse(date, template, string, j) {
5051
while (i < n) {
5152
if (j >= m) return -1;
5253
c = template.charCodeAt(i++);
53-
if (c == 37) {
54+
if (c === 37) {
5455
p = d3_time_parsers[template.charAt(i++)];
5556
if (!p || ((j = p(date, string, j)) < 0)) return -1;
5657
} else if (c != string.charCodeAt(j++)) {
@@ -70,10 +71,11 @@ function d3_time_formatLookup(names) {
7071
return map;
7172
}
7273

73-
var d3_time_zfill2 = d3.format("02d"),
74-
d3_time_zfill3 = d3.format("03d"),
75-
d3_time_zfill4 = d3.format("04d"),
76-
d3_time_sfill2 = d3.format("2d");
74+
function d3_time_formatPad(value, fill, width) {
75+
value += "";
76+
var length = value.length;
77+
return length < width ? new Array(width - length + 1).join(fill) + value : value;
78+
}
7779

7880
var d3_time_dayRe = d3_time_formatRe(d3_time_days),
7981
d3_time_dayAbbrevRe = d3_time_formatRe(d3_time_dayAbbreviations),
@@ -82,29 +84,35 @@ var d3_time_dayRe = d3_time_formatRe(d3_time_days),
8284
d3_time_monthAbbrevRe = d3_time_formatRe(d3_time_monthAbbreviations),
8385
d3_time_monthAbbrevLookup = d3_time_formatLookup(d3_time_monthAbbreviations);
8486

87+
var d3_time_formatPads = {
88+
"-": "",
89+
"_": " ",
90+
"0": "0"
91+
};
92+
8593
var d3_time_formats = {
8694
a: function(d) { return d3_time_dayAbbreviations[d.getDay()]; },
8795
A: function(d) { return d3_time_days[d.getDay()]; },
8896
b: function(d) { return d3_time_monthAbbreviations[d.getMonth()]; },
8997
B: function(d) { return d3_time_months[d.getMonth()]; },
9098
c: d3.time.format(d3_time_formatDateTime),
91-
d: function(d) { return d3_time_zfill2(d.getDate()); },
92-
e: function(d) { return d3_time_sfill2(d.getDate()); },
93-
H: function(d) { return d3_time_zfill2(d.getHours()); },
94-
I: function(d) { return d3_time_zfill2(d.getHours() % 12 || 12); },
95-
j: function(d) { return d3_time_zfill3(1 + d3.time.dayOfYear(d)); },
96-
L: function(d) { return d3_time_zfill3(d.getMilliseconds()); },
97-
m: function(d) { return d3_time_zfill2(d.getMonth() + 1); },
98-
M: function(d) { return d3_time_zfill2(d.getMinutes()); },
99+
d: function(d, p) { return d3_time_formatPad(d.getDate(), p, 2); },
100+
e: function(d, p) { return d3_time_formatPad(d.getDate(), p, 2); },
101+
H: function(d, p) { return d3_time_formatPad(d.getHours(), p, 2); },
102+
I: function(d, p) { return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); },
103+
j: function(d, p) { return d3_time_formatPad(1 + d3.time.dayOfYear(d), p, 3); },
104+
L: function(d, p) { return d3_time_formatPad(d.getMilliseconds(), p, 3); },
105+
m: function(d, p) { return d3_time_formatPad(d.getMonth() + 1, p, 2); },
106+
M: function(d, p) { return d3_time_formatPad(d.getMinutes(), p, 2); },
99107
p: function(d) { return d.getHours() >= 12 ? "PM" : "AM"; },
100-
S: function(d) { return d3_time_zfill2(d.getSeconds()); },
101-
U: function(d) { return d3_time_zfill2(d3.time.sundayOfYear(d)); },
108+
S: function(d, p) { return d3_time_formatPad(d.getSeconds(), p, 2); },
109+
U: function(d, p) { return d3_time_formatPad(d3.time.sundayOfYear(d), p, 2); },
102110
w: function(d) { return d.getDay(); },
103-
W: function(d) { return d3_time_zfill2(d3.time.mondayOfYear(d)); },
111+
W: function(d, p) { return d3_time_formatPad(d3.time.mondayOfYear(d), p, 2); },
104112
x: d3.time.format(d3_time_formatDate),
105113
X: d3.time.format(d3_time_formatTime),
106-
y: function(d) { return d3_time_zfill2(d.getFullYear() % 100); },
107-
Y: function(d) { return d3_time_zfill4(d.getFullYear() % 10000); },
114+
y: function(d, p) { return d3_time_formatPad(d.getFullYear() % 100, p, 2); },
115+
Y: function(d, p) { return d3_time_formatPad(d.getFullYear() % 10000, p, 4); },
108116
Z: d3_time_zone,
109117
"%": function(d) { return "%"; }
110118
};
@@ -247,5 +255,5 @@ function d3_time_zone(d) {
247255
zs = z > 0 ? "-" : "+",
248256
zh = ~~(Math.abs(z) / 60),
249257
zm = Math.abs(z) % 60;
250-
return zs + d3_time_zfill2(zh) + d3_time_zfill2(zm);
258+
return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2);
251259
}

test/time/format-test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ suite.addBatch({
100100
var f = format("%S");
101101
assert.equal(f(local(1990, 0, 1, 0, 0, 0)), "00");
102102
assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32");
103+
var f = format("%0S");
104+
assert.equal(f(local(1990, 0, 1, 0, 0, 0)), "00");
105+
assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32");
106+
},
107+
"formats space-padded second": function(format) {
108+
var f = format("%_S");
109+
assert.equal(f(local(1990, 0, 1, 0, 0, 0)), " 0");
110+
assert.equal(f(local(1990, 0, 1, 0, 0, 3)), " 3");
111+
assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32");
112+
},
113+
"formats no-padded second": function(format) {
114+
var f = format("%-S");
115+
assert.equal(f(local(1990, 0, 1, 0, 0, 0)), "0");
116+
assert.equal(f(local(1990, 0, 1, 0, 0, 3)), "3");
117+
assert.equal(f(local(1990, 0, 1, 0, 0, 32)), "32");
103118
},
104119
"formats zero-padded millisecond": function(format) {
105120
var f = format("%L");

0 commit comments

Comments
 (0)