time: add Duration.str() (#12897)

* time: add str() method to Duration

* add Duration.str tests, move time.infinite to time.v, to be visible to the JS backend

Co-authored-by: Delyan Angelov <delian66@gmail.com>
pull/12902/head
Miccah 2021-12-19 11:32:42 -06:00 committed by GitHub
parent 840a92c14e
commit d07975335d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 13 deletions

View File

@ -0,0 +1,33 @@
import time
fn test_duration_str() {
assert time.Duration(1 * time.nanosecond).str() == '1ns'
assert time.Duration(999 * time.nanosecond).str() == '999ns'
assert time.Duration(1000 * time.nanosecond).str() == '1.000us'
//
assert time.Duration(1 * time.microsecond).str() == '1.000us'
assert time.Duration(999 * time.microsecond).str() == '999.000us'
assert time.Duration(1000 * time.microsecond).str() == '1.000ms'
//
assert time.Duration(1 * time.second).str() == '1.000s'
assert time.Duration(999 * time.second).str() == '16:39.000'
assert time.Duration(1000 * time.second).str() == '16:40.000'
//
assert time.Duration(1 * time.minute).str() == '1:00.000'
assert time.Duration(999 * time.minute).str() == '16:39:00'
assert time.Duration(1000 * time.minute).str() == '16:40:00'
//
assert time.Duration(1 * time.hour).str() == '1:00:00'
assert time.Duration(999 * time.hour).str() == '999:00:00'
assert time.Duration(1000 * time.hour).str() == '1000:00:00'
//
assert time.Duration(1 * time.microsecond + 7 * time.nanosecond).str() == '1.007us'
//
assert time.Duration(1 * time.second + 5 * time.nanosecond).str() == '1.000s'
assert time.Duration(1 * time.second + 5 * time.microsecond).str() == '1.000s'
assert time.Duration(1 * time.second + 5 * time.millisecond).str() == '1.005s'
//
assert time.Duration(1 * time.hour + 5 * time.millisecond).str() == '1:00:00'
assert time.Duration(1 * time.hour + 5 * time.second).str() == '1:00:05'
assert time.Duration(168 * time.hour + 5 * time.minute + 7 * time.second).str() == '168:05:07'
}

View File

@ -119,7 +119,3 @@ fn convert_ctime(t C.tm, microsecond int) Time {
unix: make_unix_time(t)
}
}
pub const (
infinite = Duration(C.INT64_MAX)
)

View File

@ -7,7 +7,7 @@ pub const (
// The unsigned zero year for internal calculations.
// Must be 1 mod 400, and times before it will not compute correctly,
// but otherwise can be changed at will.
absolute_zero_year = i64(-292277022399) // as i64
absolute_zero_year = i64(-292277022399)
seconds_per_minute = 60
seconds_per_hour = 60 * seconds_per_minute
seconds_per_day = 24 * seconds_per_hour
@ -258,14 +258,19 @@ pub fn (t Time) debug() string {
// A lot of these are taken from the Go library.
pub type Duration = i64
pub const (
nanosecond = Duration(1)
microsecond = Duration(1000 * nanosecond)
millisecond = Duration(1000 * microsecond)
second = Duration(1000 * millisecond)
minute = Duration(60 * second)
hour = Duration(60 * minute)
)
pub const nanosecond = Duration(1)
pub const microsecond = Duration(1000 * nanosecond)
pub const millisecond = Duration(1000 * microsecond)
pub const second = Duration(1000 * millisecond)
pub const minute = Duration(60 * second)
pub const hour = Duration(60 * minute)
pub const infinite = Duration(i64(9223372036854775807))
// nanoseconds returns the duration as an integer number of nanoseconds.
pub fn (d Duration) nanoseconds() i64 {
@ -305,6 +310,42 @@ pub fn (d Duration) hours() f64 {
return f64(hr) + f64(nsec) / (60 * 60 * 1e9)
}
// str pretty prints the duration.
pub fn (d Duration) str() string {
if d == time.infinite {
return 'inf'
}
mut t := i64(d)
hr := t / time.hour
t -= hr * time.hour
min := t / time.minute
t -= min * time.minute
sec := t / time.second
t -= sec * time.second
ms := t / time.millisecond
t -= ms * time.millisecond
us := t / time.microsecond
t -= us * time.microsecond
ns := t
if hr > 0 {
return '$hr:${min:02}:${sec:02}'
}
if min > 0 {
return '$min:${sec:02}.${ms:03}'
}
if sec > 0 {
return '${sec}.${ms:03}s'
}
if ms > 0 {
return '${ms}.${us:03}ms'
}
if us > 0 {
return '${us}.${ns:03}us'
}
return '${ns}ns'
}
// offset returns time zone UTC offset in seconds.
pub fn offset() int {
t := now()