mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-02 15:17:31 -04:00
unix: add function for converting time.Time to Timespec
Add function TimeToTimespec for converting time.Time to Timespec. Fixes golang/go#23078. Change-Id: I685a4871d49131191f330b56b15bfd4f3131a9a5 Reviewed-on: https://go-review.googlesource.com/82919 Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
76c138986e
commit
9418b3fdda
@@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
package unix
|
package unix
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
// TimespecToNsec converts a Timespec value into a number of
|
// TimespecToNsec converts a Timespec value into a number of
|
||||||
// nanoseconds since the Unix epoch.
|
// nanoseconds since the Unix epoch.
|
||||||
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
|
||||||
@@ -22,6 +24,24 @@ func NsecToTimespec(nsec int64) Timespec {
|
|||||||
return setTimespec(sec, nsec)
|
return setTimespec(sec, nsec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TimeToTimespec converts t into a Timespec.
|
||||||
|
// On some 32-bit systems the range of valid Timespec values are smaller
|
||||||
|
// than that of time.Time values. So if t is out of the valid range of
|
||||||
|
// Timespec, it returns a zero Timespec and ERANGE.
|
||||||
|
func TimeToTimespec(t time.Time) (Timespec, error) {
|
||||||
|
sec := t.Unix()
|
||||||
|
nsec := int64(t.Nanosecond())
|
||||||
|
ts := setTimespec(sec, nsec)
|
||||||
|
|
||||||
|
// Currently all targets have either int32 or int64 for Timespec.Sec.
|
||||||
|
// If there were a new target with floating point type for it, we have
|
||||||
|
// to consider the rounding error.
|
||||||
|
if int64(ts.Sec) != sec {
|
||||||
|
return Timespec{}, ERANGE
|
||||||
|
}
|
||||||
|
return ts, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TimevalToNsec converts a Timeval value into a number of nanoseconds
|
// TimevalToNsec converts a Timeval value into a number of nanoseconds
|
||||||
// since the Unix epoch.
|
// since the Unix epoch.
|
||||||
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
// Copyright 2017 The Go Authors. All right reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||||
|
|
||||||
|
package unix_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTimeToTimespec(t *testing.T) {
|
||||||
|
timeTests := []struct {
|
||||||
|
time time.Time
|
||||||
|
valid bool
|
||||||
|
}{
|
||||||
|
{time.Unix(0, 0), true},
|
||||||
|
{time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC), true},
|
||||||
|
{time.Date(2262, time.December, 31, 23, 0, 0, 0, time.UTC), false},
|
||||||
|
{time.Unix(0x7FFFFFFF, 0), true},
|
||||||
|
{time.Unix(0x80000000, 0), false},
|
||||||
|
{time.Unix(0x7FFFFFFF, 1000000000), false},
|
||||||
|
{time.Unix(0x7FFFFFFF, 999999999), true},
|
||||||
|
{time.Unix(-0x80000000, 0), true},
|
||||||
|
{time.Unix(-0x80000001, 0), false},
|
||||||
|
{time.Date(2038, time.January, 19, 3, 14, 7, 0, time.UTC), true},
|
||||||
|
{time.Date(2038, time.January, 19, 3, 14, 8, 0, time.UTC), false},
|
||||||
|
{time.Date(1901, time.December, 13, 20, 45, 52, 0, time.UTC), true},
|
||||||
|
{time.Date(1901, time.December, 13, 20, 45, 51, 0, time.UTC), false},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Currently all targets have either int32 or int64 for Timespec.Sec.
|
||||||
|
// If there were a new target with unsigned or floating point type for
|
||||||
|
// it, this test must be adjusted.
|
||||||
|
have64BitTime := (unsafe.Sizeof(unix.Timespec{}.Sec) == 8)
|
||||||
|
for _, tt := range timeTests {
|
||||||
|
ts, err := unix.TimeToTimespec(tt.time)
|
||||||
|
tt.valid = tt.valid || have64BitTime
|
||||||
|
if tt.valid && err != nil {
|
||||||
|
t.Errorf("TimeToTimespec(%v): %v", tt.time, err)
|
||||||
|
}
|
||||||
|
if err == nil {
|
||||||
|
tstime := time.Unix(int64(ts.Sec), int64(ts.Nsec))
|
||||||
|
if !tstime.Equal(tt.time) {
|
||||||
|
t.Errorf("TimeToTimespec(%v) is the time %v", tt.time, tstime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user