diff --git a/lib/std/io/io_formatter_private.c3 b/lib/std/io/io_formatter_private.c3 index 0d638edcf..1e75c1414 100644 --- a/lib/std/io/io_formatter_private.c3 +++ b/lib/std/io/io_formatter_private.c3 @@ -141,7 +141,7 @@ fn void! Formatter.out_substr(&self, String str) @private usz l = conv::utf8_codepoints(str); uint prec = self.prec; if (self.flags.precision && l < prec) l = prec; - self.right_adjust(' ')!; + self.right_adjust(l)!; usz index = 0; usz chars = str.len; char* ptr = str.ptr; diff --git a/lib/std/time/datetime.c3 b/lib/std/time/datetime.c3 index 1636b9a61..d56bf6af8 100644 --- a/lib/std/time/datetime.c3 +++ b/lib/std/time/datetime.c3 @@ -133,24 +133,19 @@ fn Time DateTime.to_time(&self) @inline return self.time; } -fn bool DateTime.after(&self, DateTime compare) +fn bool DateTime.after(&self, DateTime compare) @inline { return self.time > compare.time; } -fn bool DateTime.before(&self, DateTime compare) +fn bool DateTime.before(&self, DateTime compare) @inline { return self.time < compare.time; } fn int DateTime.compare_to(&self, DateTime compare) { - switch - { - case self.time > compare.time: return 1; - case self.time < compare.time: return -1; - default: return 0; - } + return compare_to(self.time, compare.time); } fn int DateTime.diff_years(&self, DateTime from) diff --git a/lib/std/time/time.c3 b/lib/std/time/time.c3 index 9c540f680..25a5a47d9 100644 --- a/lib/std/time/time.c3 +++ b/lib/std/time/time.c3 @@ -84,4 +84,71 @@ fn double Time.diff_weeks(time, Time other) => (long)time.diff_us(other) / (doub fn double NanoDuration.to_sec(nd) => (double)nd / 1_000_000_000.0; fn long NanoDuration.to_ms(nd) => (long)nd / 1_000_000; fn TimeDuration NanoDuration.to_duration(nd) => (TimeDuration)nd / 1_000; -fn NanoDuration TimeDuration.to_nano(td) => (NanoDuration)td * 1_000; \ No newline at end of file +fn NanoDuration TimeDuration.to_nano(td) => (NanoDuration)td * 1_000; + +fn void! NanoDuration.to_format(&self, Formatter* formatter) @dynamic +{ + NanoDuration nd = *self; + if (nd == 0) + { + formatter.printf("0s")!; + return; + } + + bool neg = nd < 0; + if (neg) nd = -nd; + + DString str; + str.tinit(); + if (nd < 1_000_000_000) + { + // Less than 1s: print milliseconds, microseconds and nanoseconds. + NanoDuration ms = nd / 1_000_000; + if (ms > 0) + { + str.printf("%dms", ms); + nd -= ms * 1_000_000; + } + NanoDuration us = nd / 1000; + if (us > 0) + { + str.printf("%dµs", us); + nd -= us * 1000; + } + if (nd > 0) + { + str.printf("%dns", nd); + } + } + else + { + // More than 1s: print hours, minutes and seconds. + NanoDuration ms = (nd - nd / 1_000_000_000 * 1_000_000_000) / 1_000_000; + + nd /= 1_000_000_000; + NanoDuration hour = nd / 3600; + if (hour > 0) + { + str.printf("%dh", hour); + nd -= hour * 3600; + } + NanoDuration min = nd / 60; + if (min > 0) + { + str.printf("%dm", min); + nd -= min * 60; + } + NanoDuration sec = nd; + if (ms > 0) + { + // Ignore trailing zeroes. + while (ms / 10 * 10 == ms) ms /= 10; + str.printf("%d.%ds", sec, ms); + } + else + { + str.printf("%ds", sec); + } + } + formatter.printf(str.as_str())!; +} \ No newline at end of file diff --git a/test/unit/stdlib/io/printf.c3 b/test/unit/stdlib/io/printf.c3 index e506a119c..66feb321f 100644 --- a/test/unit/stdlib/io/printf.c3 +++ b/test/unit/stdlib/io/printf.c3 @@ -2,10 +2,19 @@ module std::io @test; fn void printf_a() { - assert(string::printf("%08.2a", 234.125) == "0x1.d4p+7"); - assert(string::printf("%a", 234.125) == "0x1.d44p+7"); - assert(string::printf("%A", 234.125) == "0X1.D44P+7"); - assert(string::printf("%20a", 234.125) == " 0x1.d44p+7"); - assert(string::printf("%-20a", 234.125) == "0x1.d44p+7 "); -} - + String s; + s = string::printf("%08.2a", 234.125); + assert(s == "0x1.d4p+7", "got '%s'; want '0x1.d4p+7'", s); + s = string::printf("%a", 234.125); + assert(s == "0x1.d44p+7", "got '%s'; want '0x1.d44p+7'", s); + s = string::printf("%A", 234.125); + assert(s == "0X1.D44P+7", "got '%s'; want '0X1.D44P+7'", s); + s = string::printf("%20a", 234.125); + assert(s == " 0x1.d44p+7", "got '%s'; want ' 0x1.d44p+7'", s); + s = string::printf("%-20a", 234.125); + assert(s == "0x1.d44p+7 ", "got '%s'; want '0x1.d44p+7 '", s); + s = string::printf("%-20s", "hello world"); + assert(s == "hello world ", "got '%s'; want 'hello world '", s); + s = string::printf("%20s", "hello world"); + assert(s == " hello world", "got '%s'; want ' hello world'", s); +} \ No newline at end of file diff --git a/test/unit/stdlib/time/time.c3 b/test/unit/stdlib/time/time.c3 new file mode 100644 index 000000000..afe6f199c --- /dev/null +++ b/test/unit/stdlib/time/time.c3 @@ -0,0 +1,29 @@ +module nanoduration_test @test; +import std::io; +import std::time; + +fn void! to_format() +{ + char[32] buffer; + char[] buf; + buf = io::bprintf(buffer[..], "%s", (NanoDuration)123)!; + assert(buf == "123ns", "got %s; want 123ns", buf); + + buf = io::bprintf(buffer[..], "%s", (NanoDuration)123_000)!; + assert(buf == "123µs", "got %s; want 123µs", buf); + + buf = io::bprintf(buffer[..], "%s", (NanoDuration)123_000_000)!; + assert(buf == "123ms", "got %s; want 123ms", buf); + + buf = io::bprintf(buffer[..], "%s", (NanoDuration)13_000_000_000)!; + assert(buf == "13s", "got %s; want 13s", buf); + + buf = io::bprintf(buffer[..], "%s", (NanoDuration)123_000_000_000)!; + assert(buf == "2m3s", "got %s; want 2m3s", buf); + + buf = io::bprintf(buffer[..], "%s", (NanoDuration)12345_000_000_000)!; + assert(buf == "3h25m45s", "got %s; want 3h25m45s", buf); + + buf = io::bprintf(buffer[..], "%s", (NanoDuration)12_100_000_000)!; + assert(buf == "12.1s", "got %s; want 12.1s", buf); +} \ No newline at end of file