v / vlib / time / duration.v
153 lines · 138 sloc · 3.46 KB · 4b7955afe528e233a43f8586b923529e6d28c391
Raw
1module time
2
3// A lot of these are taken from the Go library.
4pub type Duration = i64
5
6@[markused]
7pub const nanosecond = Duration(1)
8pub const microsecond = Duration(1000 * nanosecond)
9pub const millisecond = Duration(1000 * microsecond)
10pub const second = Duration(1000 * millisecond)
11pub const minute = Duration(60 * second)
12pub const hour = Duration(60 * minute)
13// day = Duration(24 * hour)
14pub const infinite = Duration(i64(9223372036854775807))
15
16// nanoseconds returns the duration as an integer number of nanoseconds.
17pub fn (d Duration) nanoseconds() i64 {
18 return i64(d)
19}
20
21// microseconds returns the duration as an integer number of microseconds.
22pub fn (d Duration) microseconds() i64 {
23 return i64(d) / microsecond
24}
25
26// milliseconds returns the duration as an integer number of milliseconds.
27pub fn (d Duration) milliseconds() i64 {
28 return i64(d) / millisecond
29}
30
31// The following functions return floating point numbers because it's common to
32// consider all of them in sub-one intervals
33// seconds returns the duration as a floating point number of seconds.
34pub fn (d Duration) seconds() f64 {
35 return f64(d) / f64(second)
36}
37
38// minutes returns the duration as a floating point number of minutes.
39pub fn (d Duration) minutes() f64 {
40 return f64(d) / f64(minute)
41}
42
43// hours returns the duration as a floating point number of hours.
44pub fn (d Duration) hours() f64 {
45 return f64(d) / f64(hour)
46}
47
48// days returns the duration as a floating point number of days.
49pub fn (d Duration) days() f64 {
50 return f64(d) / f64(hour * 24)
51}
52
53fn duration_pad2(n i64) string {
54 if n < 10 {
55 return '0' + n.str()
56 }
57 return n.str()
58}
59
60fn duration_pad3(n i64) string {
61 if n < 10 {
62 return '00' + n.str()
63 }
64 if n < 100 {
65 return '0' + n.str()
66 }
67 return n.str()
68}
69
70// str pretty prints the duration
71//
72// ```
73// h:m:s // 5:02:33
74// m:s.mi<s> // 2:33.015
75// s.mi<s> // 33.015s
76// mi.mc<ms> // 15.007ms
77// mc.ns<ns> // 7.234us
78// ns<ns> // 234ns
79// ```
80pub fn (d Duration) str() string {
81 if d == infinite {
82 return 'inf'
83 }
84 mut sign := ''
85 mut t := i64(d)
86 if t < 0 {
87 sign = '-'
88 t = -t
89 }
90 hr := t / hour
91 t -= hr * hour
92 min := t / minute
93 t -= min * minute
94 sec := t / second
95 t -= sec * second
96 ms := t / millisecond
97 t -= ms * millisecond
98 us := t / microsecond
99 t -= us * microsecond
100 ns := t
101
102 if hr > 0 {
103 return sign + hr.str() + ':' + duration_pad2(min) + ':' + duration_pad2(sec)
104 }
105 if min > 0 {
106 return sign + min.str() + ':' + duration_pad2(sec) + '.' + duration_pad3(ms)
107 }
108 if sec > 0 {
109 return sign + sec.str() + '.' + duration_pad3(ms) + 's'
110 }
111 if ms > 0 {
112 return sign + ms.str() + '.' + duration_pad3(us) + 'ms'
113 }
114 if us > 0 {
115 return sign + us.str() + '.' + duration_pad3(ns) + 'us'
116 }
117 return sign + ns.str() + 'ns'
118}
119
120// debug returns a detailed breakdown of the Duration, as: 'Duration: - 50days, 4h, 3m, 7s, 541ms, 78us, 9ns'.
121pub fn (d Duration) debug() string {
122 mut res := []string{}
123 mut x := i64(d)
124 mut sign := ''
125 if x < 0 {
126 sign = '- '
127 x = -x
128 }
129 for label, v in {
130 'days': 24 * hour
131 'h': hour
132 'm': minute
133 's': second
134 'ms': millisecond
135 'us': microsecond
136 } {
137 if x > v {
138 xx := x / v
139 x = x % v
140 res << xx.str() + label
141 }
142 }
143 if x > 0 {
144 res << x.str() + 'ns'
145 }
146 return 'Duration: ' + sign + res.join(', ')
147}
148
149// times allows you to return fractional unit durations, based on an existing duration.
150// For example, you can: `half_an_hour := time.hour.times(0.5)` .
151pub fn (d Duration) times(x f64) Duration {
152 return f64(d) * x
153}
154