]> Cypherpunks repositories - gostls13.git/commitdiff
time: add nanoseconds to the Time structure.
authorRob Pike <r@golang.org>
Fri, 5 Aug 2011 03:44:02 +0000 (13:44 +1000)
committerRob Pike <r@golang.org>
Fri, 5 Aug 2011 03:44:02 +0000 (13:44 +1000)
R=golang-dev, dsymonds, bradfitz, kevlar, rsc, r
CC=golang-dev
https://golang.org/cl/4851041

src/pkg/time/time.go
src/pkg/time/time_test.go

index a0480786aa5e7b80da5f26c2077e7785110725b8..0e05da484476e647681cc485bc0ca46b8454d289 100644 (file)
@@ -21,6 +21,7 @@ type Time struct {
        Year                 int64  // 2006 is 2006
        Month, Day           int    // Jan-2 is 1, 2
        Hour, Minute, Second int    // 15:04:05 is 15, 4, 5.
+       Nanosecond           int    // Fractional second.
        Weekday              int    // Sunday, Monday, ...
        ZoneOffset           int    // seconds east of UTC, e.g. -7*60*60 for -0700
        Zone                 string // e.g., "MST"
@@ -128,8 +129,19 @@ func SecondsToUTC(sec int64) *Time {
        return t
 }
 
+// NanosecondsToUTC converts nsec, in number of nanoseconds since the Unix epoch,
+// into a parsed Time value in the UTC time zone.
+func NanosecondsToUTC(nsec int64) *Time {
+       // This one calls SecondsToUTC rather than the other way around because
+       // that admits a much larger span of time; NanosecondsToUTC is limited
+       // to a few hundred years only.
+       t := SecondsToUTC(nsec / 1e9)
+       t.Nanosecond = int(nsec % 1e9)
+       return t
+}
+
 // UTC returns the current time as a parsed Time value in the UTC time zone.
-func UTC() *Time { return SecondsToUTC(Seconds()) }
+func UTC() *Time { return NanosecondsToUTC(Nanoseconds()) }
 
 // SecondsToLocalTime converts sec, in number of seconds since the Unix epoch,
 // into a parsed Time value in the local time zone.
@@ -141,8 +153,16 @@ func SecondsToLocalTime(sec int64) *Time {
        return t
 }
 
+// NanosecondsToLocalTime converts nsec, in number of nanoseconds since the Unix epoch,
+// into a parsed Time value in the local time zone.
+func NanosecondsToLocalTime(nsec int64) *Time {
+       t := SecondsToLocalTime(nsec / 1e9)
+       t.Nanosecond = int(nsec % 1e9)
+       return t
+}
+
 // LocalTime returns the current time as a parsed Time value in the local time zone.
-func LocalTime() *Time { return SecondsToLocalTime(Seconds()) }
+func LocalTime() *Time { return NanosecondsToLocalTime(Nanoseconds()) }
 
 // Seconds returns the number of seconds since January 1, 1970 represented by the
 // parsed Time value.
@@ -202,3 +222,9 @@ func (t *Time) Seconds() int64 {
        sec -= int64(t.ZoneOffset)
        return sec
 }
+
+// Nanoseconds returns the number of nanoseconds since January 1, 1970 represented by the
+// parsed Time value.
+func (t *Time) Nanoseconds() int64 {
+       return t.Seconds()*1e9 + int64(t.Nanosecond)
+}
index eec8a7a5ce3c1681ceb2f2331d52222528d0d067..cf37916fb905f69fe275c7c59329c59a768f4bdd 100644 (file)
@@ -37,21 +37,31 @@ type TimeTest struct {
 }
 
 var utctests = []TimeTest{
-       {0, Time{1970, 1, 1, 0, 0, 0, Thursday, 0, "UTC"}},
-       {1221681866, Time{2008, 9, 17, 20, 4, 26, Wednesday, 0, "UTC"}},
-       {-1221681866, Time{1931, 4, 16, 3, 55, 34, Thursday, 0, "UTC"}},
-       {-11644473600, Time{1601, 1, 1, 0, 0, 0, Monday, 0, "UTC"}},
-       {599529660, Time{1988, 12, 31, 0, 1, 0, Saturday, 0, "UTC"}},
-       {978220860, Time{2000, 12, 31, 0, 1, 0, Sunday, 0, "UTC"}},
-       {1e18, Time{31688740476, 10, 23, 1, 46, 40, Friday, 0, "UTC"}},
-       {-1e18, Time{-31688736537, 3, 10, 22, 13, 20, Tuesday, 0, "UTC"}},
-       {0x7fffffffffffffff, Time{292277026596, 12, 4, 15, 30, 7, Sunday, 0, "UTC"}},
-       {-0x8000000000000000, Time{-292277022657, 1, 27, 8, 29, 52, Sunday, 0, "UTC"}},
+       {0, Time{1970, 1, 1, 0, 0, 0, 0, Thursday, 0, "UTC"}},
+       {1221681866, Time{2008, 9, 17, 20, 4, 26, 0, Wednesday, 0, "UTC"}},
+       {-1221681866, Time{1931, 4, 16, 3, 55, 34, 0, Thursday, 0, "UTC"}},
+       {-11644473600, Time{1601, 1, 1, 0, 0, 0, 0, Monday, 0, "UTC"}},
+       {599529660, Time{1988, 12, 31, 0, 1, 0, 0, Saturday, 0, "UTC"}},
+       {978220860, Time{2000, 12, 31, 0, 1, 0, 0, Sunday, 0, "UTC"}},
+       {1e18, Time{31688740476, 10, 23, 1, 46, 40, 0, Friday, 0, "UTC"}},
+       {-1e18, Time{-31688736537, 3, 10, 22, 13, 20, 0, Tuesday, 0, "UTC"}},
+       {0x7fffffffffffffff, Time{292277026596, 12, 4, 15, 30, 7, 0, Sunday, 0, "UTC"}},
+       {-0x8000000000000000, Time{-292277022657, 1, 27, 8, 29, 52, 0, Sunday, 0, "UTC"}},
+}
+
+var nanoutctests = []TimeTest{
+       {0, Time{1970, 1, 1, 0, 0, 0, 1e8, Thursday, 0, "UTC"}},
+       {1221681866, Time{2008, 9, 17, 20, 4, 26, 2e8, Wednesday, 0, "UTC"}},
 }
 
 var localtests = []TimeTest{
-       {0, Time{1969, 12, 31, 16, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
-       {1221681866, Time{2008, 9, 17, 13, 4, 26, Wednesday, -7 * 60 * 60, "PDT"}},
+       {0, Time{1969, 12, 31, 16, 0, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
+       {1221681866, Time{2008, 9, 17, 13, 4, 26, 0, Wednesday, -7 * 60 * 60, "PDT"}},
+}
+
+var nanolocaltests = []TimeTest{
+       {0, Time{1969, 12, 31, 16, 0, 0, 1e8, Wednesday, -8 * 60 * 60, "PST"}},
+       {1221681866, Time{2008, 9, 17, 13, 4, 26, 3e8, Wednesday, -7 * 60 * 60, "PDT"}},
 }
 
 func same(t, u *Time) bool {
@@ -61,15 +71,16 @@ func same(t, u *Time) bool {
                t.Hour == u.Hour &&
                t.Minute == u.Minute &&
                t.Second == u.Second &&
+               t.Nanosecond == u.Nanosecond &&
                t.Weekday == u.Weekday &&
                t.ZoneOffset == u.ZoneOffset &&
                t.Zone == u.Zone
 }
 
 func TestSecondsToUTC(t *testing.T) {
-       for i := 0; i < len(utctests); i++ {
-               sec := utctests[i].seconds
-               golden := &utctests[i].golden
+       for _, test := range utctests {
+               sec := test.seconds
+               golden := &test.golden
                tm := SecondsToUTC(sec)
                newsec := tm.Seconds()
                if newsec != sec {
@@ -83,10 +94,27 @@ func TestSecondsToUTC(t *testing.T) {
        }
 }
 
+func TestNanosecondsToUTC(t *testing.T) {
+       for _, test := range nanoutctests {
+               golden := &test.golden
+               nsec := test.seconds*1e9 + int64(golden.Nanosecond)
+               tm := NanosecondsToUTC(nsec)
+               newnsec := tm.Nanoseconds()
+               if newnsec != nsec {
+                       t.Errorf("NanosecondsToUTC(%d).Nanoseconds() = %d", nsec, newnsec)
+               }
+               if !same(tm, golden) {
+                       t.Errorf("NanosecondsToUTC(%d):", nsec)
+                       t.Errorf("  want=%+v", *golden)
+                       t.Errorf("  have=%+v", *tm)
+               }
+       }
+}
+
 func TestSecondsToLocalTime(t *testing.T) {
-       for i := 0; i < len(localtests); i++ {
-               sec := localtests[i].seconds
-               golden := &localtests[i].golden
+       for _, test := range localtests {
+               sec := test.seconds
+               golden := &test.golden
                tm := SecondsToLocalTime(sec)
                newsec := tm.Seconds()
                if newsec != sec {
@@ -100,6 +128,23 @@ func TestSecondsToLocalTime(t *testing.T) {
        }
 }
 
+func TestNanoecondsToLocalTime(t *testing.T) {
+       for _, test := range nanolocaltests {
+               golden := &test.golden
+               nsec := test.seconds*1e9 + int64(golden.Nanosecond)
+               tm := NanosecondsToLocalTime(nsec)
+               newnsec := tm.Nanoseconds()
+               if newnsec != nsec {
+                       t.Errorf("NanosecondsToLocalTime(%d).Seconds() = %d", nsec, newnsec)
+               }
+               if !same(tm, golden) {
+                       t.Errorf("NanosecondsToLocalTime(%d):", nsec)
+                       t.Errorf("  want=%+v", *golden)
+                       t.Errorf("  have=%+v", *tm)
+               }
+       }
+}
+
 func TestSecondsToUTCAndBack(t *testing.T) {
        f := func(sec int64) bool { return SecondsToUTC(sec).Seconds() == sec }
        f32 := func(sec int32) bool { return f(int64(sec)) }
@@ -114,15 +159,30 @@ func TestSecondsToUTCAndBack(t *testing.T) {
        }
 }
 
+func TestNanosecondsToUTCAndBack(t *testing.T) {
+       f := func(nsec int64) bool { return NanosecondsToUTC(nsec).Nanoseconds() == nsec }
+       f32 := func(nsec int32) bool { return f(int64(nsec)) }
+       cfg := &quick.Config{MaxCount: 10000}
+
+       // Try a small date first, then the large ones. (The span is only a few hundred years
+       // for nanoseconds in an int64.)
+       if err := quick.Check(f32, cfg); err != nil {
+               t.Fatal(err)
+       }
+       if err := quick.Check(f, cfg); err != nil {
+               t.Fatal(err)
+       }
+}
+
 type TimeFormatTest struct {
        time           Time
        formattedValue string
 }
 
 var rfc3339Formats = []TimeFormatTest{
-       {Time{2008, 9, 17, 20, 4, 26, Wednesday, 0, "UTC"}, "2008-09-17T20:04:26Z"},
-       {Time{1994, 9, 17, 20, 4, 26, Wednesday, -18000, "EST"}, "1994-09-17T20:04:26-05:00"},
-       {Time{2000, 12, 26, 1, 15, 6, Wednesday, 15600, "OTO"}, "2000-12-26T01:15:06+04:20"},
+       {Time{2008, 9, 17, 20, 4, 26, 0, Wednesday, 0, "UTC"}, "2008-09-17T20:04:26Z"},
+       {Time{1994, 9, 17, 20, 4, 26, 0, Wednesday, -18000, "EST"}, "1994-09-17T20:04:26-05:00"},
+       {Time{2000, 12, 26, 1, 15, 6, 0, Wednesday, 15600, "OTO"}, "2000-12-26T01:15:06+04:20"},
 }
 
 func TestRFC3339Conversion(t *testing.T) {