Skip to content

Commit 1ad0f4a

Browse files
committed
Improve DateTools.format
* Padding for numbers is optional by adding dash (%-*). * Support day of the year (%j).
1 parent 5bc514f commit 1ad0f4a

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

std/DateTools.hx

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,11 @@ class DateTools {
4141
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
4242
];
4343

44-
private static function __format_get(d:Date, e:String):String {
44+
private static inline function __format_pad(v:Int, p:Bool, c:String="0", l:Int=2):String {
45+
return p ? StringTools.lpad(Std.string(v), c, l) : Std.string(v);
46+
}
47+
48+
private static function __format_get(d:Date, e:String, p:Bool=false):String {
4549
return switch (e) {
4650
case "%":
4751
"%";
@@ -54,24 +58,26 @@ class DateTools {
5458
case "B":
5559
MONTH_NAMES[d.getMonth()];
5660
case "C":
57-
StringTools.lpad(Std.string(Std.int(d.getFullYear() / 100)), "0", 2);
61+
__format_pad(Std.int(d.getFullYear() / 100), p);
5862
case "d":
59-
StringTools.lpad(Std.string(d.getDate()), "0", 2);
63+
__format_pad(d.getDate(), p);
6064
case "D":
6165
__format(d, "%m/%d/%y");
6266
case "e":
6367
Std.string(d.getDate());
6468
case "F":
6569
__format(d, "%Y-%m-%d");
6670
case "H", "k":
67-
StringTools.lpad(Std.string(d.getHours()), if (e == "H") "0" else " ", 2);
71+
__format_pad(d.getHours(), p, if (e == "H") "0" else " ");
72+
case "j":
73+
__format_pad(getDayOfYear(d), p, "0", 3);
6874
case "I", "l":
6975
var hour = d.getHours() % 12;
70-
StringTools.lpad(Std.string(hour == 0 ? 12 : hour), if (e == "I") "0" else " ", 2);
76+
__format_pad(hour == 0 ? 12 : hour, p, if (e == "I") "0" else " ");
7177
case "m":
72-
StringTools.lpad(Std.string(d.getMonth() + 1), "0", 2);
78+
__format_pad(d.getMonth() + 1, p);
7379
case "M":
74-
StringTools.lpad(Std.string(d.getMinutes()), "0", 2);
80+
__format_pad(d.getMinutes(), p);
7581
case "n":
7682
"\n";
7783
case "p":
@@ -83,7 +89,7 @@ class DateTools {
8389
case "s":
8490
Std.string(Std.int(d.getTime() / 1000));
8591
case "S":
86-
StringTools.lpad(Std.string(d.getSeconds()), "0", 2);
92+
__format_pad(d.getSeconds(), p);
8793
case "t":
8894
"\t";
8995
case "T":
@@ -94,7 +100,7 @@ class DateTools {
94100
case "w":
95101
Std.string(d.getDay());
96102
case "y":
97-
StringTools.lpad(Std.string(d.getFullYear() % 100), "0", 2);
103+
__format_pad(d.getFullYear() % 100, p);
98104
case "Y":
99105
Std.string(d.getFullYear());
100106
default:
@@ -105,15 +111,23 @@ class DateTools {
105111
private static function __format(d:Date, f:String):String {
106112
var r = new StringBuf();
107113
var p = 0;
114+
var pad:Bool;
108115
while (true) {
109116
var np = f.indexOf("%", p);
110117
if (np < 0)
111118
break;
112119

113120
r.addSub(f, p, np - p);
114-
r.add(__format_get(d, f.substr(np + 1, 1)));
115-
116-
p = np + 2;
121+
var c = f.substr(np + 1, 1);
122+
if (c == "-") {
123+
c = f.substr(np + 2, 1);
124+
p = np + 3;
125+
pad = false;
126+
} else {
127+
p = np + 2;
128+
pad = true;
129+
}
130+
r.add(__format_get(d, c, pad));
117131
}
118132
r.addSub(f, p, f.length - p);
119133
return r.toString();
@@ -179,6 +193,14 @@ class DateTools {
179193
return if (isB) 29 else 28;
180194
}
181195

196+
/**
197+
Returns the number of days since the beginning of the year.
198+
**/
199+
public static function getDayOfYear(d:Date):Int {
200+
var t = new Date(d.getFullYear(), 0, 0, 0, 0, 0);
201+
return Std.int((d.getTime() - t.getTime()) / DateTools.days(1)) + 1;
202+
}
203+
182204
/**
183205
Converts a number of seconds to a timestamp.
184206
**/

tests/unit/src/unitstd/DateTools.unit.hx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,31 @@
22
var d = new Date(2012, 1, 17, 1, 2, 3);
33
DateTools.getMonthDays(d) == 29;
44

5+
DateTools.format(d, "%d") == "17"; // day
6+
DateTools.format(d, "%a") == "Fri"; // abbreviated day name
7+
DateTools.format(d, "%w") == "5"; // weekday
8+
DateTools.format(d, "%b") == "Feb"; // abbreviated month name
9+
DateTools.format(d, "%B") == "February"; // full month name
10+
DateTools.format(d, "%y") == "12"; // year without century
11+
DateTools.format(d, "%Y") == "2012"; // year
12+
DateTools.format(d, "%-j") == "48"; // day of the year (no padding)
13+
514
// seconds/delta
615
var diff = DateTools.seconds(59);
716
var d2 = DateTools.delta(d, diff);
817
d2.toString() == "2012-02-17 01:03:02";
18+
DateTools.format(d2, "%F %T") == "2012-02-17 01:03:02";
19+
20+
d = new Date(2004, 4, 3, 21, 50, 39);
21+
22+
DateTools.format(d, "%-d") == "3"; // day (no padding)
23+
DateTools.format(d, "%A") == "Monday"; // day name
24+
DateTools.format(d, "%w") == "1"; // weekday
25+
DateTools.format(d, "%m") == "05"; // month
26+
DateTools.format(d, "%-m") == "5"; // month (no padding)
27+
DateTools.format(d, "%-y") == "4"; // year without century (no padding)
28+
DateTools.format(d, "%Y") == "2004"; // year
29+
DateTools.format(d, "%j") == "124"; // day of the year
930

1031
//UTC based timestamp generation
1132
#if (js || flash || php || cpp || python)

0 commit comments

Comments
 (0)