mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
time: store time with nanosecond resolution in time.Time, deprecate Time.microsecond, add utility methods and tests (#19062)
This commit is contained in:
parent
cc97b8df1e
commit
b9a523cefd
@ -74,12 +74,12 @@ fn on_frame(mut app App) {
|
||||
// draw minute hand
|
||||
mut j := f32(n.minute)
|
||||
if n.second == 59 { // make minute hand move smoothly
|
||||
j += f32(math.sin(f32(n.microsecond) / 1e6 * math.pi / 2.0))
|
||||
j += f32(math.sin(f32(n.nanosecond) / 1e9 * math.pi / 2.0))
|
||||
}
|
||||
draw_convex_poly_rotate(mut app.gg, app.dpi_scale, app.minute_hand, hand_color, j * 6)
|
||||
|
||||
// draw second hand with smooth transition
|
||||
k := f32(n.second) + f32(math.sin(f32(n.microsecond) / 1e6 * math.pi / 2.0))
|
||||
k := f32(n.second) + f32(math.sin(f32(n.nanosecond) / 1e9 * math.pi / 2.0))
|
||||
draw_convex_poly_rotate(mut app.gg, app.dpi_scale, app.second_hand, second_hand_color,
|
||||
0 + k * 6)
|
||||
|
||||
|
@ -28,7 +28,7 @@ const time_to_test = time.Time{
|
||||
hour: 21
|
||||
minute: 23
|
||||
second: 42
|
||||
microsecond: 123456
|
||||
nanosecond: 123456789
|
||||
unix: 332198622
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ assert '1980-07-11 21:23' == time_to_test.format()
|
||||
assert '1980-07-11 21:23:42' == time_to_test.format_ss()
|
||||
assert '1980-07-11 21:23:42.123' == time_to_test.format_ss_milli()
|
||||
assert '1980-07-11 21:23:42.123456' == time_to_test.format_ss_micro()
|
||||
assert '1980-07-11 21:23:42.123456789' == time_to_test.format_ss_nano()
|
||||
```
|
||||
|
||||
You can also parse strings to produce time.Time values,
|
||||
|
@ -31,3 +31,9 @@ fn test_duration_str() {
|
||||
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'
|
||||
}
|
||||
|
||||
fn test_duration_debug() {
|
||||
assert time.Duration(1 * time.nanosecond).debug() == 'Duration: 1ns'
|
||||
assert time.Duration(169 * time.hour + 5 * time.minute + 7 * time.second).debug() == 'Duration: 7days, 1h, 5m, 7s'
|
||||
assert (-time.Duration(169 * time.hour + 5 * time.minute + 7 * time.second)).debug() == 'Duration: - 7days, 1h, 5m, 7s'
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ pub fn (t Time) format_ss() string {
|
||||
|
||||
// format_ss_milli returns a date string in "YYYY-MM-DD HH:mm:ss.123" format (24h).
|
||||
pub fn (t Time) format_ss_milli() string {
|
||||
return '${t.year:04d}-${t.month:02d}-${t.day:02d} ${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${(t.microsecond / 1000):03d}'
|
||||
return '${t.year:04d}-${t.month:02d}-${t.day:02d} ${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${(t.nanosecond / 1_000_000):03d}'
|
||||
}
|
||||
|
||||
// format_rfc3339 returns a date string in "YYYY-MM-DDTHH:mm:ss.123Z" format (24 hours, see https://www.rfc-editor.org/rfc/rfc3339.html)
|
||||
@ -25,12 +25,17 @@ pub fn (t Time) format_ss_milli() string {
|
||||
// It is intended to improve consistency and interoperability, when representing and using date and time in Internet protocols.
|
||||
pub fn (t Time) format_rfc3339() string {
|
||||
u := t.local_to_utc()
|
||||
return '${u.year:04d}-${u.month:02d}-${u.day:02d}T${u.hour:02d}:${u.minute:02d}:${u.second:02d}.${(u.microsecond / 1000):03d}Z'
|
||||
return '${u.year:04d}-${u.month:02d}-${u.day:02d}T${u.hour:02d}:${u.minute:02d}:${u.second:02d}.${(u.nanosecond / 1_000_000):03d}Z'
|
||||
}
|
||||
|
||||
// format_ss_micro returns a date string in "YYYY-MM-DD HH:mm:ss.123456" format (24h).
|
||||
pub fn (t Time) format_ss_micro() string {
|
||||
return '${t.year:04d}-${t.month:02d}-${t.day:02d} ${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${t.microsecond:06d}'
|
||||
return '${t.year:04d}-${t.month:02d}-${t.day:02d} ${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${(t.nanosecond / 1_000):06d}'
|
||||
}
|
||||
|
||||
// format_ss_nano returns a date string in "YYYY-MM-DD HH:mm:ss.123456789" format (24h).
|
||||
pub fn (t Time) format_ss_nano() string {
|
||||
return '${t.year:04d}-${t.month:02d}-${t.day:02d} ${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${t.nanosecond:09d}'
|
||||
}
|
||||
|
||||
// hhmm returns a date string in "HH:mm" format (24h).
|
||||
@ -381,8 +386,9 @@ pub fn (t Time) get_fmt_time_str(fmt_time FormatTime) string {
|
||||
.hhmm24 { '${t.hour:02d}:${t.minute:02d}' }
|
||||
.hhmmss12 { '${hour_}:${t.minute:02d}:${t.second:02d} ${tp}' }
|
||||
.hhmmss24 { '${t.hour:02d}:${t.minute:02d}:${t.second:02d}' }
|
||||
.hhmmss24_milli { '${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${(t.microsecond / 1000):03d}' }
|
||||
.hhmmss24_micro { '${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${t.microsecond:06d}' }
|
||||
.hhmmss24_milli { '${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${(t.nanosecond / 1_000_000):03d}' }
|
||||
.hhmmss24_micro { '${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${(t.nanosecond / 1_000):06d}' }
|
||||
.hhmmss24_nano { '${t.hour:02d}:${t.minute:02d}:${t.second:02d}.${t.nanosecond:06d}' }
|
||||
else { 'unknown enumeration ${fmt_time}' }
|
||||
}
|
||||
}
|
||||
|
@ -3,19 +3,22 @@ module time
|
||||
// operator `==` returns true if provided time is equal to time
|
||||
[inline]
|
||||
pub fn (t1 Time) == (t2 Time) bool {
|
||||
return t1.unix == t2.unix && t1.microsecond == t2.microsecond
|
||||
return t1.unix == t2.unix && t1.nanosecond == t2.nanosecond
|
||||
}
|
||||
|
||||
// operator `<` returns true if provided time is less than time
|
||||
[inline]
|
||||
pub fn (t1 Time) < (t2 Time) bool {
|
||||
return t1.unix < t2.unix || (t1.unix == t2.unix && t1.microsecond < t2.microsecond)
|
||||
return t1.unix < t2.unix || (t1.unix == t2.unix && t1.nanosecond < t2.nanosecond)
|
||||
}
|
||||
|
||||
// Time subtract using operator overloading.
|
||||
[inline]
|
||||
pub fn (lhs Time) - (rhs Time) Duration {
|
||||
lhs_micro := lhs.unix * 1_000_000 + lhs.microsecond
|
||||
rhs_micro := rhs.unix * 1_000_000 + rhs.microsecond
|
||||
return (lhs_micro - rhs_micro) * microsecond
|
||||
// lhs.unix * 1_000_000_000 + i64(lhs.nanosecond) will overflow i64, for years > 3000 .
|
||||
// Doing the diff first, and *then* multiplying by `second`, is less likely to overflow,
|
||||
// since lhs and rhs will be likely close to each other.
|
||||
unixs := i64(lhs.unix - rhs.unix) * second
|
||||
nanos := lhs.nanosecond - rhs.nanosecond
|
||||
return unixs + nanos
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ fn test_time1_should_be_same_as_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
@ -48,7 +48,7 @@ fn test_time1_should_be_same_as_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
assert t1 == t2
|
||||
}
|
||||
@ -61,9 +61,9 @@ fn test_time1_should_not_be_same_as_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
// Difference is one microsecond
|
||||
// Difference is one nanosecond
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -71,7 +71,7 @@ fn test_time1_should_not_be_same_as_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 101
|
||||
nanosecond: 101
|
||||
})
|
||||
t3 := new_time(Time{
|
||||
year: 2000
|
||||
@ -80,7 +80,7 @@ fn test_time1_should_not_be_same_as_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
// Difference is one second
|
||||
t4 := new_time(Time{
|
||||
@ -90,7 +90,7 @@ fn test_time1_should_not_be_same_as_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 4
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
assert t1 != t2
|
||||
assert t3 != t4
|
||||
@ -104,9 +104,9 @@ fn test_time1_should_be_greater_than_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 102
|
||||
nanosecond: 102
|
||||
})
|
||||
// Difference is one microsecond
|
||||
// Difference is one nanosecond
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -114,7 +114,7 @@ fn test_time1_should_be_greater_than_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 101
|
||||
nanosecond: 101
|
||||
})
|
||||
t3 := new_time(Time{
|
||||
year: 2000
|
||||
@ -123,7 +123,7 @@ fn test_time1_should_be_greater_than_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 5
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
// Difference is one second
|
||||
t4 := new_time(Time{
|
||||
@ -133,7 +133,7 @@ fn test_time1_should_be_greater_than_time2() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 4
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
assert t1 > t2
|
||||
assert t3 > t4
|
||||
@ -147,9 +147,9 @@ fn test_time2_should_be_less_than_time1() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 102
|
||||
nanosecond: 102
|
||||
})
|
||||
// Difference is one microsecond
|
||||
// Difference is one nanosecond
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -157,7 +157,7 @@ fn test_time2_should_be_less_than_time1() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 101
|
||||
nanosecond: 101
|
||||
})
|
||||
t3 := new_time(Time{
|
||||
year: 2000
|
||||
@ -166,7 +166,7 @@ fn test_time2_should_be_less_than_time1() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
// Difference is one second
|
||||
t4 := new_time(Time{
|
||||
@ -176,7 +176,7 @@ fn test_time2_should_be_less_than_time1() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 2
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
assert t2 < t1
|
||||
assert t4 < t3
|
||||
@ -190,9 +190,9 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_gt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 102
|
||||
nanosecond: 102
|
||||
})
|
||||
// Difference is one microsecond
|
||||
// Difference is one nanosecond
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -200,7 +200,7 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_gt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 101
|
||||
nanosecond: 101
|
||||
})
|
||||
t3 := new_time(Time{
|
||||
year: 2000
|
||||
@ -209,7 +209,7 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_gt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 5
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
// Difference is one second
|
||||
t4 := new_time(Time{
|
||||
@ -219,7 +219,7 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_gt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 4
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
assert t1 >= t2
|
||||
assert t3 >= t4
|
||||
@ -233,9 +233,9 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
// Difference is one microsecond
|
||||
// Difference is one nanosecond
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -243,7 +243,7 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
t3 := new_time(Time{
|
||||
year: 2000
|
||||
@ -252,7 +252,7 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
// Difference is one second
|
||||
t4 := new_time(Time{
|
||||
@ -262,7 +262,7 @@ fn test_time1_should_be_greater_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
assert t1 >= t2
|
||||
assert t3 >= t4
|
||||
@ -276,9 +276,9 @@ fn test_time1_should_be_less_or_equal_to_time2_when_lt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
// Difference is one microsecond
|
||||
// Difference is one nanosecond
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -286,7 +286,7 @@ fn test_time1_should_be_less_or_equal_to_time2_when_lt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 101
|
||||
nanosecond: 101
|
||||
})
|
||||
t3 := new_time(Time{
|
||||
year: 2000
|
||||
@ -295,7 +295,7 @@ fn test_time1_should_be_less_or_equal_to_time2_when_lt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
// Difference is one second
|
||||
t4 := new_time(Time{
|
||||
@ -305,7 +305,7 @@ fn test_time1_should_be_less_or_equal_to_time2_when_lt() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 4
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
assert t1 <= t2
|
||||
assert t3 <= t4
|
||||
@ -319,9 +319,9 @@ fn test_time1_should_be_less_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
// Difference is one microsecond
|
||||
// Difference is one nanosecond
|
||||
t2 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -329,7 +329,7 @@ fn test_time1_should_be_less_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
t3 := new_time(Time{
|
||||
year: 2000
|
||||
@ -338,7 +338,7 @@ fn test_time1_should_be_less_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
// Difference is one second
|
||||
t4 := new_time(Time{
|
||||
@ -348,7 +348,7 @@ fn test_time1_should_be_less_or_equal_to_time2_when_eq() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 0
|
||||
nanosecond: 0
|
||||
})
|
||||
assert t1 <= t2
|
||||
assert t3 <= t4
|
||||
@ -362,7 +362,7 @@ fn test_time2_copied_from_time1_should_be_equal() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
t2 := new_time(t1)
|
||||
assert t2 == t1
|
||||
@ -370,8 +370,8 @@ fn test_time2_copied_from_time1_should_be_equal() {
|
||||
|
||||
fn test_subtract() {
|
||||
d_seconds := 3
|
||||
d_microseconds := 13
|
||||
duration := d_seconds * second + d_microseconds * microsecond
|
||||
d_nanoseconds := 13
|
||||
duration := d_seconds * second + d_nanoseconds * nanosecond
|
||||
t1 := new_time(Time{
|
||||
year: 2000
|
||||
month: 5
|
||||
@ -379,9 +379,9 @@ fn test_subtract() {
|
||||
hour: 22
|
||||
minute: 11
|
||||
second: 3
|
||||
microsecond: 100
|
||||
nanosecond: 100
|
||||
})
|
||||
t2 := unix2(i64(t1.unix) + d_seconds, t1.microsecond + d_microseconds)
|
||||
t2 := unix_nanosecond(i64(t1.unix) + d_seconds, t1.nanosecond + d_nanoseconds)
|
||||
d1 := t2 - t1
|
||||
d2 := t1 - t2
|
||||
assert d1 > 0
|
||||
|
@ -35,13 +35,13 @@ pub fn parse_rfc3339(s string) !Time {
|
||||
}
|
||||
// Check if sn is time only
|
||||
if !parts[0].contains('-') && parts[0].contains(':') {
|
||||
mut hour_, mut minute_, mut second_, mut microsecond_, mut unix_offset, mut is_local_time := 0, 0, 0, 0, i64(0), true
|
||||
hour_, minute_, second_, microsecond_, unix_offset, is_local_time = parse_iso8601_time(parts[0])!
|
||||
mut hour_, mut minute_, mut second_, mut microsecond_, mut nanosecond_, mut unix_offset, mut is_local_time := 0, 0, 0, 0, 0, i64(0), true
|
||||
hour_, minute_, second_, microsecond_, nanosecond_, unix_offset, is_local_time = parse_iso8601_time(parts[0])!
|
||||
t = new_time(Time{
|
||||
hour: hour_
|
||||
minute: minute_
|
||||
second: second_
|
||||
microsecond: microsecond_
|
||||
nanosecond: nanosecond_
|
||||
})
|
||||
if is_local_time {
|
||||
return t // Time is already local time
|
||||
@ -52,7 +52,7 @@ pub fn parse_rfc3339(s string) !Time {
|
||||
} else if unix_offset > 0 {
|
||||
unix_time += unix_offset
|
||||
}
|
||||
t = unix2(i64(unix_time), t.microsecond)
|
||||
t = unix_nanosecond(i64(unix_time), t.nanosecond)
|
||||
return t
|
||||
}
|
||||
|
||||
@ -171,9 +171,9 @@ pub fn parse_iso8601(s string) !Time {
|
||||
return error_invalid_time(12, 'malformed date')
|
||||
}
|
||||
year, month, day := parse_iso8601_date(parts[0])!
|
||||
mut hour_, mut minute_, mut second_, mut microsecond_, mut unix_offset, mut is_local_time := 0, 0, 0, 0, i64(0), true
|
||||
mut hour_, mut minute_, mut second_, mut microsecond_, mut nanosecond_, mut unix_offset, mut is_local_time := 0, 0, 0, 0, 0, i64(0), true
|
||||
if parts.len == 2 {
|
||||
hour_, minute_, second_, microsecond_, unix_offset, is_local_time = parse_iso8601_time(parts[1])!
|
||||
hour_, minute_, second_, microsecond_, nanosecond_, unix_offset, is_local_time = parse_iso8601_time(parts[1])!
|
||||
}
|
||||
mut t := new_time(
|
||||
year: year
|
||||
@ -182,7 +182,7 @@ pub fn parse_iso8601(s string) !Time {
|
||||
hour: hour_
|
||||
minute: minute_
|
||||
second: second_
|
||||
microsecond: microsecond_
|
||||
nanosecond: nanosecond_
|
||||
)
|
||||
if is_local_time {
|
||||
return t // Time already local time
|
||||
@ -193,7 +193,7 @@ pub fn parse_iso8601(s string) !Time {
|
||||
} else if unix_offset > 0 {
|
||||
unix_time += unix_offset
|
||||
}
|
||||
t = unix2(i64(unix_time), t.microsecond)
|
||||
t = unix_nanosecond(i64(unix_time), t.nanosecond)
|
||||
return t
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ fn parse_iso8601_date(s string) !(int, int, int) {
|
||||
return year, month, day
|
||||
}
|
||||
|
||||
fn parse_iso8601_time(s string) !(int, int, int, int, i64, bool) {
|
||||
fn parse_iso8601_time(s string) !(int, int, int, int, int, i64, bool) {
|
||||
hour_ := 0
|
||||
minute_ := 0
|
||||
second_ := 0
|
||||
@ -281,6 +281,7 @@ fn parse_iso8601_time(s string) !(int, int, int, int, i64, bool) {
|
||||
if count < 4 {
|
||||
return error_invalid_time(10, 'malformed date')
|
||||
}
|
||||
nanosecond_ = microsecond_ * 1000
|
||||
}
|
||||
is_local_time := plus_min_z == `a` && count == 4
|
||||
is_utc := plus_min_z == `Z` && count == 5
|
||||
@ -300,5 +301,6 @@ fn parse_iso8601_time(s string) !(int, int, int, int, i64, bool) {
|
||||
if plus_min_z == `+` {
|
||||
unix_offset *= -1
|
||||
}
|
||||
return hour_, minute_, second_, microsecond_, unix_offset, is_local_time
|
||||
// eprintln('parse_iso8601_time s: $s | hour_: $hour_ | minute_: $minute_ | second_: $second_ | microsecond_: $microsecond_ | nanosecond_: $nanosecond_ | unix_offset: $unix_offset | is_local_time: $is_local_time')
|
||||
return hour_, minute_, second_, microsecond_, nanosecond_, unix_offset, is_local_time
|
||||
}
|
||||
|
@ -65,11 +65,11 @@ fn test_parse_iso8601() {
|
||||
]
|
||||
times := [
|
||||
[2020, 6, 5, 15, 38, 6, 0],
|
||||
[2020, 6, 5, 15, 38, 6, 15959],
|
||||
[2020, 6, 5, 15, 38, 6, 15959],
|
||||
[2020, 6, 5, 13, 38, 6, 15959],
|
||||
[2020, 6, 5, 17, 38, 6, 15959],
|
||||
[2020, 11, 5, 15, 38, 6, 15959],
|
||||
[2020, 6, 5, 15, 38, 6, 15959000],
|
||||
[2020, 6, 5, 15, 38, 6, 15959000],
|
||||
[2020, 6, 5, 13, 38, 6, 15959000],
|
||||
[2020, 6, 5, 17, 38, 6, 15959000],
|
||||
[2020, 11, 5, 15, 38, 6, 15959000],
|
||||
]
|
||||
for i, format in formats {
|
||||
t := time.parse_iso8601(format) or {
|
||||
@ -89,8 +89,8 @@ fn test_parse_iso8601() {
|
||||
assert t.minute == minute
|
||||
second := times[i][5]
|
||||
assert t.second == second
|
||||
microsecond := times[i][6]
|
||||
assert t.microsecond == microsecond
|
||||
nanosecond := times[i][6]
|
||||
assert t.nanosecond == nanosecond
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ fn test_parse_iso8601_local() {
|
||||
assert t.hour == 15
|
||||
assert t.minute == 38
|
||||
assert t.second == 6
|
||||
assert t.microsecond == 15959
|
||||
assert t.nanosecond == 15959_000
|
||||
}
|
||||
|
||||
fn test_parse_iso8601_invalid() {
|
||||
@ -145,7 +145,7 @@ fn test_parse_iso8601_date_only() {
|
||||
assert t.hour == 0
|
||||
assert t.minute == 0
|
||||
assert t.second == 0
|
||||
assert t.microsecond == 0
|
||||
assert t.nanosecond == 0
|
||||
}
|
||||
|
||||
fn check_invalid_date(s string) {
|
||||
|
@ -53,13 +53,6 @@ pub fn utc() Time {
|
||||
return solaris_utc()
|
||||
}
|
||||
return linux_utc()
|
||||
/*
|
||||
// defaults to most common feature, the microsecond precision is not available
|
||||
// in this API call
|
||||
t := C.time(0)
|
||||
_ = C.time(&t)
|
||||
return unix2(i64(t), 0)
|
||||
*/
|
||||
}
|
||||
|
||||
// new_time returns a time struct with the calculated Unix time.
|
||||
@ -90,7 +83,7 @@ pub fn ticks() i64 {
|
||||
} $else {
|
||||
ts := C.timeval{}
|
||||
C.gettimeofday(&ts, 0)
|
||||
return i64(ts.tv_sec * u64(1000) + (ts.tv_usec / u64(1000)))
|
||||
return i64(ts.tv_sec * u64(1000) + (ts.tv_usec / u64(1_000)))
|
||||
}
|
||||
// t := i64(C.mach_absolute_time())
|
||||
// # Nanoseconds elapsedNano = AbsoluteToNanoseconds( *(AbsoluteTime *) &t );
|
||||
@ -105,7 +98,7 @@ pub fn (t Time) str() string {
|
||||
}
|
||||
|
||||
// convert_ctime converts a C time to V time.
|
||||
fn convert_ctime(t C.tm, microsecond int) Time {
|
||||
fn convert_ctime(t C.tm, nanosecond int) Time {
|
||||
return Time{
|
||||
year: t.tm_year + 1900
|
||||
month: t.tm_mon + 1
|
||||
@ -113,7 +106,7 @@ fn convert_ctime(t C.tm, microsecond int) Time {
|
||||
hour: t.tm_hour
|
||||
minute: t.tm_min
|
||||
second: t.tm_sec
|
||||
microsecond: microsecond
|
||||
nanosecond: nanosecond
|
||||
unix: make_unix_time(t)
|
||||
// for the actual code base when we
|
||||
// call convert_ctime, it is always
|
||||
|
109
vlib/time/time.v
109
vlib/time/time.v
@ -40,15 +40,17 @@ pub const (
|
||||
// Time contains various time units for a point in time.
|
||||
pub struct Time {
|
||||
pub:
|
||||
year int
|
||||
month int
|
||||
day int
|
||||
hour int
|
||||
minute int
|
||||
second int
|
||||
microsecond int
|
||||
unix i64
|
||||
is_local bool // used to make time.now().local().local() == time.now().local()
|
||||
year int
|
||||
month int
|
||||
day int
|
||||
hour int
|
||||
minute int
|
||||
second int
|
||||
nanosecond int
|
||||
unix i64
|
||||
is_local bool // used to make time.now().local().local() == time.now().local()
|
||||
//
|
||||
microsecond int [deprecated: 'use t.nanosecond / 1000 instead'; deprecated_after: '2023-08-05']
|
||||
}
|
||||
|
||||
// FormatDelimiter contains different time formats.
|
||||
@ -59,6 +61,7 @@ pub enum FormatTime {
|
||||
hhmmss24
|
||||
hhmmss24_milli
|
||||
hhmmss24_micro
|
||||
hhmmss24_nano
|
||||
no_time
|
||||
}
|
||||
|
||||
@ -99,7 +102,7 @@ pub fn (t Time) smonth() string {
|
||||
return time.months_string[i * 3..(i + 1) * 3]
|
||||
}
|
||||
|
||||
// unix_time returns the UNIX time.
|
||||
// unix_time returns the UNIX time with second resolution.
|
||||
[inline]
|
||||
pub fn (t Time) unix_time() i64 {
|
||||
return t.unix
|
||||
@ -108,18 +111,39 @@ pub fn (t Time) unix_time() i64 {
|
||||
// unix_time_milli returns the UNIX time with millisecond resolution.
|
||||
[inline]
|
||||
pub fn (t Time) unix_time_milli() i64 {
|
||||
return t.unix * 1000 + (t.microsecond / 1000)
|
||||
return t.unix * 1_000 + (i64(t.nanosecond) / 1_000_000)
|
||||
}
|
||||
|
||||
// unix_time_micro returns the UNIX time with microsecond resolution.
|
||||
[inline]
|
||||
pub fn (t Time) unix_time_micro() i64 {
|
||||
return t.unix * 1_000_000 + (i64(t.nanosecond) / 1_000)
|
||||
}
|
||||
|
||||
// unix_time_nano returns the UNIX time with nanosecond resolution.
|
||||
[inline]
|
||||
pub fn (t Time) unix_time_nano() i64 {
|
||||
// TODO: use i128 here, when V supports it, since the following expression overflows for years like 3001:
|
||||
return t.unix * 1_000_000_000 + i64(t.nanosecond)
|
||||
}
|
||||
|
||||
// add returns a new time with the given duration added.
|
||||
pub fn (t Time) add(d Duration) Time {
|
||||
microseconds := i64(t.unix) * 1_000_000 + t.microsecond + d.microseconds()
|
||||
unix := microseconds / 1_000_000
|
||||
micro := microseconds % 1_000_000
|
||||
if t.is_local {
|
||||
return unix2(unix, int(micro)).as_local()
|
||||
// This expression overflows i64 for big years (and we do not have i128 yet):
|
||||
// nanos := t.unix * 1_000_000_000 + i64(t.nanosecond) <-
|
||||
// ... so instead, handle the addition manually in parts ¯\_(ツ)_/¯
|
||||
mut unixs := t.unix
|
||||
mut nanos := i64(t.nanosecond) + d.nanoseconds()
|
||||
unixs += nanos / time.second
|
||||
nanos = nanos % time.second
|
||||
if nanos < 0 {
|
||||
unixs--
|
||||
nanos += time.second
|
||||
}
|
||||
return unix2(unix, int(micro))
|
||||
if t.is_local {
|
||||
return unix_nanosecond(unixs, int(nanos)).as_local()
|
||||
}
|
||||
return unix_nanosecond(unixs, int(nanos))
|
||||
}
|
||||
|
||||
// add_seconds returns a new time struct with an added number of seconds.
|
||||
@ -311,9 +335,9 @@ pub fn days_in_month(month int, year int) !int {
|
||||
return res
|
||||
}
|
||||
|
||||
// debug returns detailed breakdown of time (`Time{ year: YYYY month: MM day: dd hour: HH: minute: mm second: ss microsecond: micros unix: unix }`)
|
||||
// debug returns detailed breakdown of time (`Time{ year: YYYY month: MM day: dd hour: HH: minute: mm second: ss nanosecond: nanos unix: unix }`)
|
||||
pub fn (t Time) debug() string {
|
||||
return 'Time{ year: ${t.year:04} month: ${t.month:02} day: ${t.day:02} hour: ${t.hour:02} minute: ${t.minute:02} second: ${t.second:02} microsecond: ${t.microsecond:06} unix: ${t.unix:07} }'
|
||||
return 'Time{ year: ${t.year:04} month: ${t.month:02} day: ${t.day:02} hour: ${t.hour:02} minute: ${t.minute:02} second: ${t.second:02} nanosecond: ${t.nanosecond:09} unix: ${t.unix:07} }'
|
||||
}
|
||||
|
||||
// A lot of these are taken from the Go library.
|
||||
@ -326,6 +350,7 @@ pub const (
|
||||
second = Duration(1000 * millisecond)
|
||||
minute = Duration(60 * second)
|
||||
hour = Duration(60 * minute)
|
||||
// day = Duration(24 * hour)
|
||||
infinite = Duration(i64(9223372036854775807))
|
||||
)
|
||||
|
||||
@ -348,23 +373,22 @@ pub fn (d Duration) milliseconds() i64 {
|
||||
// consider all of them in sub-one intervals
|
||||
// seconds returns the duration as a floating point number of seconds.
|
||||
pub fn (d Duration) seconds() f64 {
|
||||
sec := d / time.second
|
||||
nsec := d % time.second
|
||||
return f64(sec) + f64(nsec) / time.second
|
||||
return f64(d) / f64(time.second)
|
||||
}
|
||||
|
||||
// minutes returns the duration as a floating point number of minutes.
|
||||
pub fn (d Duration) minutes() f64 {
|
||||
min := d / time.minute
|
||||
nsec := d % time.minute
|
||||
return f64(min) + f64(nsec) / time.minute
|
||||
return f64(d) / f64(time.minute)
|
||||
}
|
||||
|
||||
// hours returns the duration as a floating point number of hours.
|
||||
pub fn (d Duration) hours() f64 {
|
||||
hr := d / time.hour
|
||||
nsec := d % time.hour
|
||||
return f64(hr) + f64(nsec) / time.hour
|
||||
return f64(d) / f64(time.hour)
|
||||
}
|
||||
|
||||
// days returns the duration as a floating point number of days.
|
||||
pub fn (d Duration) days() f64 {
|
||||
return f64(d) / f64(time.hour * 24)
|
||||
}
|
||||
|
||||
// str pretty prints the duration
|
||||
@ -412,6 +436,35 @@ pub fn (d Duration) str() string {
|
||||
return '${ns}ns'
|
||||
}
|
||||
|
||||
// debug returns a detailed breakdown of the Duration, as: 'Duration: - 50days, 4h, 3m, 7s, 541ms, 78us, 9ns'
|
||||
pub fn (d Duration) debug() string {
|
||||
mut res := []string{}
|
||||
mut x := i64(d)
|
||||
mut sign := ''
|
||||
if x < 0 {
|
||||
sign = '- '
|
||||
x = -x
|
||||
}
|
||||
for label, v in {
|
||||
'days': 24 * time.hour
|
||||
'h': time.hour
|
||||
'm': time.minute
|
||||
's': time.second
|
||||
'ms': time.millisecond
|
||||
'us': time.microsecond
|
||||
} {
|
||||
if x > v {
|
||||
xx := x / v
|
||||
x = x % v
|
||||
res << xx.str() + label
|
||||
}
|
||||
}
|
||||
if x > 0 {
|
||||
res << '${x}ns'
|
||||
}
|
||||
return 'Duration: ${sign}${res.join(', ')}'
|
||||
}
|
||||
|
||||
// offset returns time zone UTC offset in seconds.
|
||||
pub fn offset() int {
|
||||
t := utc()
|
||||
|
@ -3,8 +3,6 @@ import time
|
||||
fn test_add_to_day_in_the_previous_century() {
|
||||
a := time.parse_iso8601('1900-01-01')!
|
||||
aa := a.add_days(180)
|
||||
dump(a.debug())
|
||||
dump(aa.debug())
|
||||
assert aa.ymmdd() == '1900-06-30'
|
||||
}
|
||||
|
||||
@ -23,6 +21,8 @@ fn test_add_to_day_in_the_recent_past() {
|
||||
fn test_add_to_day_in_the_future_1() {
|
||||
a := time.parse_iso8601('3000-11-01')!
|
||||
aa := a.add_days(180)
|
||||
dump(a.debug())
|
||||
dump(aa.debug())
|
||||
assert aa.ymmdd() == '3001-04-30'
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,10 @@ module time
|
||||
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
const (
|
||||
// start_time is needed on Darwin and Windows because of potential overflows
|
||||
start_time = C.mach_absolute_time()
|
||||
time_base = init_time_base()
|
||||
)
|
||||
// start_time is needed on Darwin and Windows because of potential overflows
|
||||
const start_time = C.mach_absolute_time()
|
||||
|
||||
const time_base = init_time_base()
|
||||
|
||||
[typedef]
|
||||
struct C.mach_timebase_info_data_t {
|
||||
@ -25,11 +24,6 @@ struct InternalTimeBase {
|
||||
denom u32 = 1
|
||||
}
|
||||
|
||||
pub struct C.timeval {
|
||||
tv_sec u64
|
||||
tv_usec u64
|
||||
}
|
||||
|
||||
fn init_time_base() C.mach_timebase_info_data_t {
|
||||
tb := C.mach_timebase_info_data_t{}
|
||||
C.mach_timebase_info(&tb)
|
||||
@ -62,29 +56,22 @@ fn vpc_now_darwin() u64 {
|
||||
return (tm - time.start_time) * time.time_base.numer / time.time_base.denom
|
||||
}
|
||||
|
||||
// darwin_now returns a better precision current time for Darwin based operating system
|
||||
// this should be implemented with native system calls eventually
|
||||
// but for now a bit tweaky. It uses the deprecated gettimeofday clock to get
|
||||
// the microseconds seconds part and converts to local time
|
||||
// darwin_now returns a better precision current time for macos
|
||||
fn darwin_now() Time {
|
||||
// get the high precision time as UTC clock
|
||||
tv := C.timeval{}
|
||||
C.gettimeofday(&tv, 0)
|
||||
// get the high precision time as UTC realtime clock, and use the nanoseconds part
|
||||
mut ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
||||
loc_tm := C.tm{}
|
||||
asec := voidptr(&tv.tv_sec)
|
||||
C.localtime_r(asec, &loc_tm)
|
||||
return convert_ctime(loc_tm, int(tv.tv_usec))
|
||||
C.localtime_r(voidptr(&ts.tv_sec), &loc_tm)
|
||||
return convert_ctime(loc_tm, int(ts.tv_nsec))
|
||||
}
|
||||
|
||||
// darwin_utc returns a better precision current time for Darwin based operating system
|
||||
// this should be implemented with native system calls eventually
|
||||
// but for now a bit tweaky. It uses the deprecated gettimeofday clock to get
|
||||
// the microseconds seconds part and normal local time to get correct local time
|
||||
// darwin_utc returns a better precision current time for macos
|
||||
fn darwin_utc() Time {
|
||||
// get the high precision time as UTC clock
|
||||
tv := C.timeval{}
|
||||
C.gettimeofday(&tv, 0)
|
||||
return unix2(i64(tv.tv_sec), int(tv.tv_usec))
|
||||
mut ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
||||
return unix_nanosecond(i64(ts.tv_sec), int(ts.tv_nsec))
|
||||
}
|
||||
|
||||
// dummy to compile with all compilers
|
||||
|
@ -36,7 +36,7 @@ pub fn (t Time) local() Time {
|
||||
}
|
||||
loc_tm := C.tm{}
|
||||
C.localtime_r(voidptr(&t.unix), &loc_tm)
|
||||
return convert_ctime(loc_tm, t.microsecond)
|
||||
return convert_ctime(loc_tm, t.nanosecond)
|
||||
}
|
||||
|
||||
// in most systems, these are __quad_t, which is an i64
|
||||
@ -58,7 +58,7 @@ pub fn sys_mono_now() u64 {
|
||||
} $else {
|
||||
ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_MONOTONIC, &ts)
|
||||
return u64(ts.tv_sec) * 1000000000 + u64(ts.tv_nsec)
|
||||
return u64(ts.tv_sec) * 1_000_000_000 + u64(ts.tv_nsec)
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ pub fn sys_mono_now() u64 {
|
||||
fn vpc_now() u64 {
|
||||
ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_MONOTONIC, &ts)
|
||||
return u64(ts.tv_sec) * 1000000000 + u64(ts.tv_nsec)
|
||||
return u64(ts.tv_sec) * 1_000_000_000 + u64(ts.tv_nsec)
|
||||
}
|
||||
|
||||
// The linux_* functions are placed here, since they're used on Android as well
|
||||
@ -83,7 +83,7 @@ fn linux_now() Time {
|
||||
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
||||
loc_tm := C.tm{}
|
||||
C.localtime_r(voidptr(&ts.tv_sec), &loc_tm)
|
||||
return convert_ctime(loc_tm, int(ts.tv_nsec / 1000))
|
||||
return convert_ctime(loc_tm, int(ts.tv_nsec))
|
||||
}
|
||||
|
||||
fn linux_utc() Time {
|
||||
@ -91,7 +91,7 @@ fn linux_utc() Time {
|
||||
// and use the nanoseconds part
|
||||
mut ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
||||
return unix2(i64(ts.tv_sec), int(ts.tv_nsec / 1000))
|
||||
return unix_nanosecond(i64(ts.tv_sec), int(ts.tv_nsec))
|
||||
}
|
||||
|
||||
// dummy to compile with all compilers
|
||||
@ -104,12 +104,6 @@ fn win_utc() Time {
|
||||
return Time{}
|
||||
}
|
||||
|
||||
// dummy to compile with all compilers
|
||||
pub struct C.timeval {
|
||||
tv_sec u64
|
||||
tv_usec u64
|
||||
}
|
||||
|
||||
// return absolute timespec for now()+d
|
||||
pub fn (d Duration) timespec() C.timespec {
|
||||
mut ts := C.timespec{}
|
||||
|
@ -10,7 +10,7 @@ fn solaris_now() Time {
|
||||
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
||||
loc_tm := C.tm{}
|
||||
C.localtime_r(voidptr(&ts.tv_sec), &loc_tm)
|
||||
return convert_ctime(loc_tm, int(ts.tv_nsec / 1000))
|
||||
return convert_ctime(loc_tm, int(ts.tv_nsec))
|
||||
}
|
||||
|
||||
fn solaris_utc() Time {
|
||||
@ -18,7 +18,7 @@ fn solaris_utc() Time {
|
||||
// and use the nanoseconds part
|
||||
mut ts := C.timespec{}
|
||||
C.clock_gettime(C.CLOCK_REALTIME, &ts)
|
||||
return unix2(i64(ts.tv_sec), int(ts.tv_nsec / 1000))
|
||||
return unix_nanosecond(i64(ts.tv_sec), int(ts.tv_nsec))
|
||||
}
|
||||
|
||||
// dummy to compile with all compilers
|
||||
|
@ -1,18 +1,16 @@
|
||||
import time
|
||||
import math
|
||||
|
||||
const (
|
||||
time_to_test = time.Time{
|
||||
year: 1980
|
||||
month: 7
|
||||
day: 11
|
||||
hour: 21
|
||||
minute: 23
|
||||
second: 42
|
||||
microsecond: 123456
|
||||
unix: 332198622
|
||||
}
|
||||
)
|
||||
const time_to_test = time.Time{
|
||||
year: 1980
|
||||
month: 7
|
||||
day: 11
|
||||
hour: 21
|
||||
minute: 23
|
||||
second: 42
|
||||
nanosecond: 123456789
|
||||
unix: 332198622
|
||||
}
|
||||
|
||||
fn test_is_leap_year() {
|
||||
// 1996 % 4 = 0 and 1996 % 100 > 0
|
||||
@ -83,6 +81,14 @@ fn test_unix() {
|
||||
assert t6.second == 29
|
||||
}
|
||||
|
||||
fn test_format_rfc3339() {
|
||||
// assert '1980-07-11T19:23:42.123Z'
|
||||
res := time_to_test.format_rfc3339()
|
||||
assert res.ends_with('23:42.123Z')
|
||||
assert res.starts_with('1980-07-1')
|
||||
assert res.contains('T')
|
||||
}
|
||||
|
||||
fn test_format_ss() {
|
||||
assert '11.07.1980 21:23:42' == time_to_test.get_fmt_str(.dot, .hhmmss24, .ddmmyyyy)
|
||||
}
|
||||
@ -93,20 +99,18 @@ fn test_format_ss_milli() {
|
||||
assert '1980-07-11 21:23:42.123' == time_to_test.format_ss_milli()
|
||||
}
|
||||
|
||||
fn test_format_rfc3339() {
|
||||
// assert '1980-07-11T19:23:42.123Z'
|
||||
res := time_to_test.format_rfc3339()
|
||||
assert res.ends_with('23:42.123Z')
|
||||
assert res.starts_with('1980-07-1')
|
||||
assert res.contains('T')
|
||||
}
|
||||
|
||||
fn test_format_ss_micro() {
|
||||
assert '11.07.1980 21:23:42.123456' == time_to_test.get_fmt_str(.dot, .hhmmss24_micro,
|
||||
.ddmmyyyy)
|
||||
assert '1980-07-11 21:23:42.123456' == time_to_test.format_ss_micro()
|
||||
}
|
||||
|
||||
fn test_format_ss_nano() {
|
||||
assert '11.07.1980 21:23:42.123456789' == time_to_test.get_fmt_str(.dot, .hhmmss24_nano,
|
||||
.ddmmyyyy)
|
||||
assert '1980-07-11 21:23:42.123456789' == time_to_test.format_ss_nano()
|
||||
}
|
||||
|
||||
fn test_smonth() {
|
||||
month_names := ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov',
|
||||
'Dec']
|
||||
@ -180,21 +184,29 @@ fn test_weekday_str() {
|
||||
|
||||
fn test_add() {
|
||||
d_seconds := 3
|
||||
d_microseconds := 13
|
||||
duration := time.Duration(d_seconds * time.second + d_microseconds * time.microsecond)
|
||||
d_nanoseconds := 13
|
||||
duration := time.Duration(d_seconds * time.second + d_nanoseconds * time.nanosecond)
|
||||
// dump(duration.debug())
|
||||
t1 := time_to_test
|
||||
// dump(t1.debug())
|
||||
t2 := time_to_test.add(duration)
|
||||
// dump(t2.debug())
|
||||
assert t2.second == t1.second + d_seconds
|
||||
assert t2.microsecond == t1.microsecond + d_microseconds
|
||||
assert t2.nanosecond == t1.nanosecond + d_nanoseconds
|
||||
assert t2.unix == t1.unix + d_seconds
|
||||
assert t2.is_local == t1.is_local
|
||||
//
|
||||
t3 := time_to_test.add(-duration)
|
||||
// dump(t3.debug())
|
||||
assert t3.second == t1.second - d_seconds
|
||||
assert t3.microsecond == t1.microsecond - d_microseconds
|
||||
assert t3.nanosecond == t1.nanosecond - d_nanoseconds
|
||||
assert t3.unix == t1.unix - d_seconds
|
||||
assert t3.is_local == t1.is_local
|
||||
//
|
||||
t4 := time_to_test.as_local()
|
||||
// dump(t4.debug())
|
||||
t5 := t4.add(duration)
|
||||
// dump(t5.debug())
|
||||
assert t5.is_local == t4.is_local
|
||||
}
|
||||
|
||||
@ -220,13 +232,14 @@ fn test_now() {
|
||||
assert now.minute < 60
|
||||
assert now.second >= 0
|
||||
assert now.second <= 60 // <= 60 cause of leap seconds
|
||||
assert now.microsecond >= 0
|
||||
assert now.microsecond < 1000000
|
||||
assert now.nanosecond >= 0
|
||||
assert now.nanosecond < time.second
|
||||
}
|
||||
|
||||
fn test_utc() {
|
||||
now := time.utc()
|
||||
// The year the test was built
|
||||
// dump(now.debug())
|
||||
assert now.year >= 2020
|
||||
assert now.month > 0
|
||||
assert now.month <= 12
|
||||
@ -234,20 +247,20 @@ fn test_utc() {
|
||||
assert now.minute < 60
|
||||
assert now.second >= 0
|
||||
assert now.second <= 60 // <= 60 cause of leap seconds
|
||||
assert now.microsecond >= 0
|
||||
assert now.microsecond < 1000000
|
||||
assert now.nanosecond >= 0
|
||||
assert now.nanosecond < time.second
|
||||
}
|
||||
|
||||
fn test_unix_time() {
|
||||
t1 := time.utc()
|
||||
time.sleep(50 * time.millisecond)
|
||||
t2 := time.utc()
|
||||
eprintln('t1: ${t1}')
|
||||
eprintln('t2: ${t2}')
|
||||
eprintln(' t1: ${t1}')
|
||||
eprintln(' t2: ${t2}')
|
||||
ut1 := t1.unix_time()
|
||||
ut2 := t2.unix_time()
|
||||
eprintln('ut1: ${ut1}')
|
||||
eprintln('ut2: ${ut2}')
|
||||
eprintln(' ut1: ${ut1}')
|
||||
eprintln(' ut2: ${ut2}')
|
||||
assert ut2 - ut1 < 2
|
||||
//
|
||||
utm1 := t1.unix_time_milli()
|
||||
|
@ -39,6 +39,8 @@ fn C.SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation &C.TIME_ZONE_INFORMAT
|
||||
|
||||
fn C.localtime_s(t &C.time_t, tm &C.tm)
|
||||
|
||||
fn C.timespec_get(t &C.timespec, base int) int
|
||||
|
||||
const (
|
||||
// start_time is needed on Darwin and Windows because of potential overflows
|
||||
start_time = init_win_time_start()
|
||||
@ -107,7 +109,7 @@ pub fn (t Time) local() Time {
|
||||
hour: u16(t.hour)
|
||||
minute: u16(t.minute)
|
||||
second: u16(t.second)
|
||||
millisecond: u16(t.microsecond / 1000)
|
||||
millisecond: u16(t.nanosecond / 1_000_000)
|
||||
}
|
||||
st_local := SystemTime{}
|
||||
C.SystemTimeToTzSpecificLocalTime(unsafe { nil }, &st_utc, &st_local)
|
||||
@ -118,7 +120,7 @@ pub fn (t Time) local() Time {
|
||||
hour: st_local.hour
|
||||
minute: st_local.minute
|
||||
second: st_local.second // These are the same
|
||||
microsecond: int(st_local.millisecond) * 1000
|
||||
nanosecond: int(st_local.millisecond) * 1_000_000
|
||||
unix: st_local.unix_time()
|
||||
}
|
||||
return t_local
|
||||
@ -141,7 +143,7 @@ fn win_now() Time {
|
||||
hour: st_local.hour
|
||||
minute: st_local.minute
|
||||
second: st_local.second
|
||||
microsecond: int(st_local.millisecond) * 1000
|
||||
nanosecond: int(st_local.millisecond) * 1_000_000
|
||||
unix: st_local.unix_time()
|
||||
is_local: true
|
||||
}
|
||||
@ -163,7 +165,7 @@ fn win_utc() Time {
|
||||
hour: st_utc.hour
|
||||
minute: st_utc.minute
|
||||
second: st_utc.second
|
||||
microsecond: int(st_utc.millisecond) * 1000
|
||||
nanosecond: int(st_utc.millisecond) * 1_000_000
|
||||
unix: st_utc.unix_time()
|
||||
is_local: false
|
||||
}
|
||||
@ -213,12 +215,6 @@ fn solaris_utc() Time {
|
||||
return Time{}
|
||||
}
|
||||
|
||||
// dummy to compile with all compilers
|
||||
pub struct C.timeval {
|
||||
tv_sec u64
|
||||
tv_usec u64
|
||||
}
|
||||
|
||||
// sleep makes the calling thread sleep for a given duration (in nanoseconds).
|
||||
pub fn sleep(duration Duration) {
|
||||
C.Sleep(int(duration / millisecond))
|
||||
|
@ -3,7 +3,7 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module time
|
||||
|
||||
// unix returns a time struct from Unix time.
|
||||
// unix returns a time struct from an Unix timestamp (number of seconds since 1970-01-01)
|
||||
pub fn unix(abs i64) Time {
|
||||
// Split into day and time
|
||||
mut day_offset := abs / seconds_per_day
|
||||
@ -24,8 +24,20 @@ pub fn unix(abs i64) Time {
|
||||
}
|
||||
}
|
||||
|
||||
// unix2 returns a time struct from Unix time and microsecond value
|
||||
// unix2 returns a Time struct, given an Unix timestamp in seconds, and a microsecond value
|
||||
[deprecated: 'use unix_microsecond(unix_ts, us) instead']
|
||||
[deprecated_after: '2023-09-05']
|
||||
pub fn unix2(abs i64, microsecond int) Time {
|
||||
return unix_nanosecond(abs, microsecond * 1000)
|
||||
}
|
||||
|
||||
// unix_microsecond returns a Time struct, given an Unix timestamp in seconds, and a microsecond value
|
||||
pub fn unix_microsecond(abs i64, microsecond int) Time {
|
||||
return unix_nanosecond(abs, microsecond * 1000)
|
||||
}
|
||||
|
||||
// unix_nanosecond returns a Time struct, given an Unix timestamp in seconds, and a nanosecond value
|
||||
pub fn unix_nanosecond(abs i64, nanosecond int) Time {
|
||||
// Split into day and time
|
||||
mut day_offset := abs / seconds_per_day
|
||||
if abs % seconds_per_day < 0 {
|
||||
@ -41,7 +53,7 @@ pub fn unix2(abs i64, microsecond int) Time {
|
||||
hour: hr
|
||||
minute: min
|
||||
second: sec
|
||||
microsecond: microsecond
|
||||
nanosecond: nanosecond
|
||||
unix: abs
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user