From 9e589d7df780732b0ff03cef4ef3e5115d4e641c Mon Sep 17 00:00:00 2001 From: Matt Tuttle Date: Sat, 29 Oct 2022 16:04:51 -0500 Subject: [PATCH 1/2] Improve DateTools.format * Padding for numbers is optional by adding dash (%-*). * Support day of the year (%j). --- std/DateTools.hx | 51 ++++++++++++++++++------ tests/unit/src/unitstd/DateTools.unit.hx | 21 ++++++++++ 2 files changed, 60 insertions(+), 12 deletions(-) diff --git a/std/DateTools.hx b/std/DateTools.hx index 32d5a63aec2..404e2743147 100644 --- a/std/DateTools.hx +++ b/std/DateTools.hx @@ -41,7 +41,11 @@ class DateTools { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; - private static function __format_get(d:Date, e:String):String { + private static inline function __format_pad(v:Int, p:Bool, c:String="0", l:Int=2):String { + return p ? StringTools.lpad(Std.string(v), c, l) : Std.string(v); + } + + private static function __format_get(d:Date, e:String, p:Bool=false):String { return switch (e) { case "%": "%"; @@ -54,9 +58,9 @@ class DateTools { case "B": MONTH_NAMES[d.getMonth()]; case "C": - StringTools.lpad(Std.string(Std.int(d.getFullYear() / 100)), "0", 2); + __format_pad(Std.int(d.getFullYear() / 100), p); case "d": - StringTools.lpad(Std.string(d.getDate()), "0", 2); + __format_pad(d.getDate(), p); case "D": __format(d, "%m/%d/%y"); case "e": @@ -64,14 +68,16 @@ class DateTools { case "F": __format(d, "%Y-%m-%d"); case "H", "k": - StringTools.lpad(Std.string(d.getHours()), if (e == "H") "0" else " ", 2); + __format_pad(d.getHours(), p, if (e == "H") "0" else " "); + case "j": + __format_pad(getDayOfYear(d), p, "0", 3); case "I", "l": var hour = d.getHours() % 12; - StringTools.lpad(Std.string(hour == 0 ? 12 : hour), if (e == "I") "0" else " ", 2); + __format_pad(hour == 0 ? 12 : hour, p, if (e == "I") "0" else " "); case "m": - StringTools.lpad(Std.string(d.getMonth() + 1), "0", 2); + __format_pad(d.getMonth() + 1, p); case "M": - StringTools.lpad(Std.string(d.getMinutes()), "0", 2); + __format_pad(d.getMinutes(), p); case "n": "\n"; case "p": @@ -83,7 +89,7 @@ class DateTools { case "s": Std.string(Std.int(d.getTime() / 1000)); case "S": - StringTools.lpad(Std.string(d.getSeconds()), "0", 2); + __format_pad(d.getSeconds(), p); case "t": "\t"; case "T": @@ -94,7 +100,7 @@ class DateTools { case "w": Std.string(d.getDay()); case "y": - StringTools.lpad(Std.string(d.getFullYear() % 100), "0", 2); + __format_pad(d.getFullYear() % 100, p); case "Y": Std.string(d.getFullYear()); default: @@ -105,15 +111,23 @@ class DateTools { private static function __format(d:Date, f:String):String { var r = new StringBuf(); var p = 0; + var pad:Bool; while (true) { var np = f.indexOf("%", p); if (np < 0) break; r.addSub(f, p, np - p); - r.add(__format_get(d, f.substr(np + 1, 1))); - - p = np + 2; + var c = f.substr(np + 1, 1); + if (c == "-") { + c = f.substr(np + 2, 1); + p = np + 3; + pad = false; + } else { + p = np + 2; + pad = true; + } + r.add(__format_get(d, c, pad)); } r.addSub(f, p, f.length - p); return r.toString(); @@ -179,6 +193,19 @@ class DateTools { return if (isB) 29 else 28; } + /** + Returns the number of days since the beginning of the year. + **/ + public static function getDayOfYear(d:Date):Int { + var startOfYear = new Date(d.getFullYear(), 0, 0, 0, 0, 0); + var days = Std.int((d.getTime() - startOfYear.getTime()) / DateTools.days(1)); + #if (neko || php || python) + return days + 1; + #else + return days; + #end + } + /** Converts a number of seconds to a timestamp. **/ diff --git a/tests/unit/src/unitstd/DateTools.unit.hx b/tests/unit/src/unitstd/DateTools.unit.hx index adceb29a6a9..1da085b7382 100644 --- a/tests/unit/src/unitstd/DateTools.unit.hx +++ b/tests/unit/src/unitstd/DateTools.unit.hx @@ -2,10 +2,31 @@ var d = new Date(2012, 1, 17, 1, 2, 3); DateTools.getMonthDays(d) == 29; +DateTools.format(d, "%d") == "17"; // day +DateTools.format(d, "%a") == "Fri"; // abbreviated day name +DateTools.format(d, "%w") == "5"; // weekday +DateTools.format(d, "%b") == "Feb"; // abbreviated month name +DateTools.format(d, "%B") == "February"; // full month name +DateTools.format(d, "%y") == "12"; // year without century +DateTools.format(d, "%Y") == "2012"; // year +DateTools.format(d, "%-j") == "48"; // day of the year (no padding) + // seconds/delta var diff = DateTools.seconds(59); var d2 = DateTools.delta(d, diff); d2.toString() == "2012-02-17 01:03:02"; +DateTools.format(d2, "%F %T") == "2012-02-17 01:03:02"; + +d = new Date(2004, 4, 3, 21, 50, 39); + +DateTools.format(d, "%-d") == "3"; // day (no padding) +DateTools.format(d, "%A") == "Monday"; // day name +DateTools.format(d, "%w") == "1"; // weekday +DateTools.format(d, "%m") == "05"; // month +DateTools.format(d, "%-m") == "5"; // month (no padding) +DateTools.format(d, "%-y") == "4"; // year without century (no padding) +DateTools.format(d, "%Y") == "2004"; // year +DateTools.format(d, "%j") == "124"; // day of the year //UTC based timestamp generation #if (js || flash || php || cpp || python) From c7dbc93624c6bd8feaa5db9e68347d2348b6d626 Mon Sep 17 00:00:00 2001 From: Simon Krajewski Date: Sun, 27 Apr 2025 06:57:01 +0200 Subject: [PATCH 2/2] Update DateTools.hx --- std/DateTools.hx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/std/DateTools.hx b/std/DateTools.hx index 404e2743147..d848a6a8424 100644 --- a/std/DateTools.hx +++ b/std/DateTools.hx @@ -199,11 +199,11 @@ class DateTools { public static function getDayOfYear(d:Date):Int { var startOfYear = new Date(d.getFullYear(), 0, 0, 0, 0, 0); var days = Std.int((d.getTime() - startOfYear.getTime()) / DateTools.days(1)); - #if (neko || php || python) - return days + 1; - #else - return days; - #end + #if (neko || php || python) + return days + 1; + #else + return days; + #end } /**