Conrad Irwin has uploaded this change for review.
time: add UnixMilli and UnixMicro
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 76 insertions(+), 0 deletions(-)
diff --git a/src/time/time.go b/src/time/time.go
index 8ae6230..26160f0 100644
--- a/src/time/time.go
+++ b/src/time/time.go
@@ -1138,6 +1138,20 @@
return (t.unixSec())*1e9 + int64(t.nsec())
}
+// UnixMilli returns t as a Unix time, the number of milliseconds elapsed
+// since January 1, 1970 UTC. The result does not depend on the
+// location associated with t.
+func (t Time) UnixMilli() int64 {
+ return (t.unixSec())*1e3 + int64(t.nsec())/1e6
+}
+
+// UnixMicro returns t as a Unix time, the number of microseconds elapsed
+// since January 1, 1970 UTC. The result does not depend on the
+// location associated with t.
+func (t Time) UnixMicro() int64 {
+ return (t.unixSec())*1e6 + int64(t.nsec())/1e3
+}
+
const timeBinaryVersion byte = 1
// MarshalBinary implements the encoding.BinaryMarshaler interface.
@@ -1302,6 +1316,18 @@
return unixTime(sec, int32(nsec))
}
+// UnixMilli returns the local Time corresponding to the given Unix time,
+// msec milliseconds since January 1, 1970 UTC.
+func UnixMilli(msec int64) Time {
+ return unixTime(msec/1e3, int32((msec%1e3)*1e6))
+}
+
+// UnixMicro returns the local Time corresponding to the given Unix time,
+// msec milliseconds since January 1, 1970 UTC.
+func UnixMicro(msec int64) Time {
+ return unixTime(msec/1e6, int32((msec%1e6)*1e3))
+}
+
func isLeap(year int) bool {
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
}
diff --git a/src/time/time_test.go b/src/time/time_test.go
index 154198a..6eab276 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -80,6 +80,20 @@
{1221681866, parsedTime{2008, September, 17, 13, 4, 26, 3e8, Wednesday, -7 * 60 * 60, "PDT"}},
}
+var millitests = []TimeTest{
+ {1617408000, parsedTime{2021, April, 3, 0, 0, 0, 567 * 1e6, Saturday, 0, "UTC"}},
+ // test outside of the range of UnixNano()
+ {-30610224000, parsedTime{1000, January, 1, 0, 0, 0, 0, Wednesday, 0, "UTC"}},
+ {32503680000, parsedTime{3000, January, 1, 0, 0, 0, 0, Wednesday, 0, "UTC"}},
+}
+
+var microtests = []TimeTest{
+ {1617408000, parsedTime{2021, April, 3, 0, 0, 0, 567891 * 1e3, Saturday, 0, "UTC"}},
+ // test outside of the range of UnixNano()
+ {-30610224000, parsedTime{1000, January, 1, 0, 0, 0, 0, Wednesday, 0, "UTC"}},
+ {32503680000, parsedTime{3000, January, 1, 0, 0, 0, 0, Wednesday, 0, "UTC"}},
+}
+
func same(t Time, u *parsedTime) bool {
// Check aggregates.
year, month, day := t.Date()
@@ -135,6 +149,40 @@
}
}
+func TestMillisecondsToUTC(t *testing.T) {
+ for _, test := range millitests {
+ golden := &test.golden
+ msec := int64(test.seconds)*1e3 + int64(golden.Nanosecond)/1e6
+ tm := UnixMilli(msec).UTC()
+ newmsec := tm.UnixMilli()
+ if newmsec != msec {
+ t.Errorf("MillisecondsToUTC(%d).Milliseconds() = %d", msec, newmsec)
+ }
+ if !same(tm, golden) {
+ t.Errorf("MillisecondsToUTC(%d):", msec)
+ t.Errorf(" want=%+v", *golden)
+ t.Errorf(" have=%+v: %+v", tm.Format(RFC3339Nano), tm.UnixNano())
+ }
+ }
+}
+
+func TestMicrosecondsToUTC(t *testing.T) {
+ for _, test := range millitests {
+ golden := &test.golden
+ msec := int64(test.seconds)*1e6 + int64(golden.Nanosecond)/1e3
+ tm := UnixMicro(msec).UTC()
+ newmsec := tm.UnixMicro()
+ if newmsec != msec {
+ t.Errorf("MicrosecondsToUTC(%d).Microseconds() = %d", msec, newmsec)
+ }
+ if !same(tm, golden) {
+ t.Errorf("MicrosecondsToUTC(%d):", msec)
+ t.Errorf(" want=%+v", *golden)
+ t.Errorf(" have=%+v: %+v", tm.Format(RFC3339Nano), tm.UnixNano())
+ }
+ }
+}
+
func TestSecondsToLocalTime(t *testing.T) {
for _, test := range localtests {
sec := test.seconds
@@ -1249,6 +1297,8 @@
{"Unix", func(t1, t2 Time) bool { return t1.Unix() == t2.Unix() }},
{"UnixNano", func(t1, t2 Time) bool { return t1.UnixNano() == t2.UnixNano() }},
+ {"UnixMilli", func(t1, t2 Time) bool { return t1.UnixMilli() == t2.UnixMilli() }},
+ {"UnixMicro", func(t1, t2 Time) bool { return t1.UnixMicro() == t2.UnixMicro() }},
{"MarshalBinary", func(t1, t2 Time) bool {
a1, b1 := t1.MarshalBinary()
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Russ Cox.
2 comments:
File src/time/time.go:
Patch Set #1, Line 1141: // UnixMilli returns t as a Unix time, the number of milliseconds elapsed
Seems like the docs for the UnixMilli ad UnixMicro methods should duplicate the UnixNano docs, including a mention of which dates are not defined.
Patch Set #1, Line 1321: func UnixMilli(msec int64) Time {
The proposal is only to add the methods. There is no UnixNano function in the time package.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Russ Cox.
Conrad Irwin uploaded patch set #2 to this change.
time: add UnixMilli and UnixMicro
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 87 insertions(+), 0 deletions(-)
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Ian Lance Taylor, Russ Cox.
2 comments:
File src/time/time.go:
Patch Set #1, Line 1141: // UnixMilli returns t as a Unix time, the number of milliseconds elapsed
Seems like the docs for the UnixMilli ad UnixMicro methods should duplicate the UnixNano docs, inclu […]
Thanks for the suggestion! I've added these.
Because the time range for millis is so large I've left it approximate, but would be happy to make it more precise if you think that would be better.
One concern I have with this is that it documents that the time.Time struct supports dates from year -290M to +290M. Currently the range supported by time.Time is not documented - is that intentional to allow flexibility in implementation? If so, is it ok to commit to supporting -290M - +290M?
(the range calculations are here if you want to check my work: https://play.golang.org/p/_UkqlJ5AEYM)
Patch Set #1, Line 1321: func UnixMilli(msec int64) Time {
The proposal is only to add the methods. There is no UnixNano function in the time package.
I misunderstood that, sorry.
What's the best way propose adding these methods too? Assuming it's not in a debate in code review, should I create a new proposal, or update the existing proposal to add these methods?
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Russ Cox.
1 comment:
File src/time/time.go:
Patch Set #1, Line 1321: func UnixMilli(msec int64) Time {
I misunderstood that, sorry. […]
Since the UnixMilli/UnixMicro proposal has already been accepted, if you want to add new functions you should file a new proposal. Thanks. Note that it will be hard to justify UnixMilli and UnixMicro functions without a UnixNano function, but of course UnixNano is already kind of covered by the Unix function.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Russ Cox.
Conrad Irwin uploaded patch set #3 to this change.
time: add Time.UnixMilli and Time.UnixMicro
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 41 insertions(+), 0 deletions(-)
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Ian Lance Taylor, Russ Cox.
2 comments:
File src/time/time.go:
Patch Set #1, Line 1141: // UnixMilli returns t as a Unix time, the number of milliseconds elapsed
Thanks for the suggestion! I've added these. […]
I realize I asked a question in this comment, but then resolved it so it may not have been seen. I'm unresolving just in case:
One concern I have with this is that it documents that the time.Time struct supports dates from year -290M to +290M. Currently the range supported by time.Time is not documented - is that intentional to allow flexibility in implementation? If so, is it ok to commit to supporting -290M - +290M?
Patch Set #1, Line 1321: func UnixMilli(msec int64) Time {
Since the UnixMilli/UnixMicro proposal has already been accepted, if you want to add new functions y […]
Thanks, I've updated this change to not add those for now, and opened golang.org/issue/44412 proposing them.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Ian Lance Taylor, Russ Cox.
1 comment:
Patchset:
Ian,
Since the UnixMilli/UnixMicro proposal has already been accepted,
It looks like https://github.com/golang/go/issues/44196 is still in the "active" proposal state.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Caleb Spare, Russ Cox.
1 comment:
Patchset:
Ian, […]
Whoops, you're quite right, my mistake. For some reason I thought it had already been accepted.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Caleb Spare, Russ Cox.
Conrad Irwin uploaded patch set #4 to this change.
time: add UnixMilli and UnixMicro
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 60 insertions(+), 0 deletions(-)
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Caleb Spare, Russ Cox.
Conrad Irwin uploaded patch set #5 to this change.
time: add UnixMilli and UnixMicro
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 60 insertions(+), 0 deletions(-)
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Caleb Spare, Russ Cox.
Patch set 5:Run-TryBot +1
Attention is currently required from: Conrad Irwin, Caleb Spare, Russ Cox.
1 comment:
Patchset:
RELNOTE=yes
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Caleb Spare, Russ Cox.
Patch set 5:Code-Review +2
1 comment:
Patchset:
Thanks.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Ian Lance Taylor, Rob Pike, Russ Cox.
Patch set 5:Code-Review -1
8 comments:
Commit Message:
Patch Set #5, Line 7: time: add UnixMilli and UnixMicro
This subject doesn't reflect that we've got new methods on time.Time. How about:
time: add Time.(UnixMicro, UnixMilli) methods and to-Time helpers UnixMicro, UnixMilli
Patchset:
Thank you for this change, Conrad! Thank you for the reviews Caleb and Ian!
Conrad, please find my review and suggestions.
Please also add entries in time_test.go for mallocTest, as well as BenchmarkNowUnix* mirroring
BenchmarkNowUnixNano.
Kindly also adding Rob Pike to take a look too.
File src/time/time.go:
a date more than 290 million
// years into the past or the future
This is an ambiguous and subjective time and not something that users can easily think about, we need an exact frame of reference, just like all the other methods give absolute years.
Patch Set #5, Line 1154: return (t.unixSec())*1e3 + int64(t.nsec())/1e6
I guess this could have been:
return t.UnixNano() / 1e6
which would be much more direct, easy to audit and understand.
There was a claim that it would be more expensive to use the division,
but this code does exactly use a division so we are on par.
Could we perhaps use this much simpler form?
Patch Set #5, Line 1163: return (t.unixSec())*1e6 + int64(t.nsec())/1e3
return t.UnixNano() / 1e3
Much easier to audit, and understand.
if msec%1e3 < 0 {
return unixTime(msec/1e3-1, int32((msec%1e3)*1e6)+1e9)
The only way that we can get a modulus < 0 is if msec < 0. This is an expensive way (a division then a comparison) and also a complicated/non-directed way to communicate that. We should be using just: msec < 0, and have these cases:
if msec < 0 {
return ...
} else if msec == 0 {
return ...
} else {
return
}
if usec%1e6 < 0 {
return unixTime(usec/1e6-1, int32((usec%1e6)*1e3)+1e9)
Ditto here about usec%1e6 ever being < 0 iff usec < 0 thus please mirror the feedback I provided above.
Patch Set #5, Line 1349: usec/1e6-1
Please explain or simplify these calculations right here, why the usec/1e6-1?
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Rob Pike, Russ Cox, Emmanuel Odeke.
2 comments:
File src/time/time.go:
Patch Set #5, Line 1154: return (t.unixSec())*1e3 + int64(t.nsec())/1e6
I guess this could have been: […]
That would have different overflow behavior. We shouldn't make this change.
Patch Set #5, Line 1163: return (t.unixSec())*1e6 + int64(t.nsec())/1e3
return t.UnixNano() / 1e3 […]
Ack
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Rob Pike, Russ Cox, Emmanuel Odeke.
Conrad Irwin uploaded patch set #6 to this change.
time: add Time.Unix{Milli,Micro} and to-Time helpers UnixMicro, UnixMilli
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 68 insertions(+), 0 deletions(-)
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Rob Pike, Russ Cox, Emmanuel Odeke.
8 comments:
Commit Message:
Patch Set #5, Line 7: time: add UnixMilli and UnixMicro
This subject doesn't reflect that we've got new methods on time.Time. How about: […]
Done
Patchset:
Thanks for the review Emmanuel!
File src/time/time.go:
a date more than 290 million
// years into the past or the future
This is an ambiguous and subjective time and not something that users can easily think about, we nee […]
I've updated this to (a date more than 292 million years before or after 1970) does that feel less subjective to you?
I am trying to avoid copying the format from UnixNano exactly because "(a date before the year -292275055 or after 292278994)" seems much worse for something that users can easily think about.
Patch Set #5, Line 1154: return (t.unixSec())*1e3 + int64(t.nsec())/1e6
I guess this could have been: […]
I don't think the approach you suggest is ideal, because it will not work for values outside of the UnixNano range (1970 +/- 292 years). (And while I don't expect that to come up often, it does seem nice to support it properly so that `UnixMilli(x).UnixMilli() == x` for every int64 value `x`).
From the benchmarks, this method is approximately the same speed as UnixNano, so I don't think the division is a problem in practice.
goos: darwin
goarch: amd64
pkg: time
cpu: Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
BenchmarkNowUnixNano-12 13474168 81.26 ns/op
BenchmarkNowUnixMilli-12 14538103 79.22 ns/op
BenchmarkNowUnixMicro-12 15024663 80.96 ns/op
Patch Set #5, Line 1163: return (t.unixSec())*1e6 + int64(t.nsec())/1e3
return t.UnixNano() / 1e3 […]
Similar to above I think it's best to keep this as is
if msec%1e3 < 0 {
return unixTime(msec/1e3-1, int32((msec%1e3)*1e6)+1e9)
The only way that we can get a modulus < 0 is if msec < 0. […]
Good call on simplifying this!
As part of your suggestion on benchmarking I ran some comparisons, and it turns out that it's about 0.01ns slower (on an operation that takes about 1ns) to just call UnixNano from here, but I think that is much easier to understand (and it already handles the negatives correctly).
Patch Set #5, Line 1349: usec/1e6-1
Please explain or simplify these calculations right here, why the usec/1e6-1?
I'm replacing this by a call to UnixNano as above.
The problem the code was trying to solve is that negative non-integer numbers are typically represented as a negative integer + a negative non-integer component; but the time class represents negative non-integer times as negative integer seconds + positive integer nanoseconds.
E.g. if the number passed was -1000001 microseconds, we can read that as -1 seconds and -1000 nanoseconds. As the time class needs nanoseconds to be positive, we subtract 1 from the seconds and add 1e9 nanoseconds to change the representation to -2 seconds + 999999000 nanoseconds.
if usec%1e6 < 0 {
return unixTime(usec/1e6-1, int32((usec%1e6)*1e3)+1e9)
Ditto here about usec%1e6 ever being < 0 iff usec < 0 thus please mirror the feedback I provided abo […]
I'm replacing this by a call to UnixNano as above.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin, Ian Lance Taylor, Rob Pike, Russ Cox.
Patch set 6:Run-TryBot +1Code-Review +2
6 comments:
Patchset:
LGTM, thank you Conrad for the changes, and for the review Ian.
File src/time/time.go:
Patch Set #1, Line 1141: // UnixMilli returns t as a Unix time, the number of milliseconds elapsed
I realize I asked a question in this comment, but then resolved it so it may not have been seen. […]
I think the current changes answer Ian’s original concern.
File src/time/time.go:
a date more than 290 million
// years into the past or the future
I've updated this to (a date more than 292 million years before or after 1970) does that feel less […]
The new change is much better, as it has a solid time reference/anchor of 1970. Thank you!
Patch Set #5, Line 1154: return (t.unixSec())*1e3 + int64(t.nsec())/1e6
I don't think the approach you suggest is ideal, because it will not work for values outside of the […]
Gotcha, thanks Conrad and Ian.
Patch Set #5, Line 1163: return (t.unixSec())*1e6 + int64(t.nsec())/1e3
Similar to above I think it's best to keep this as is
Roger that, thanks Conrad and Ian.
Patch Set #5, Line 1349: usec/1e6-1
I'm replacing this by a call to UnixNano as above. […]
The newer code is much more direct, and simpler.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin.
1 comment:
Patchset:
Nit: unnecessary parentheses in the methods before divisions, please either bring in the denominators into the operation and parentheses, or omit them entirely given that precedence will allow the operations to bind normal.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin.
2 comments:
File src/time/time.go:
Patch Set #6, Line 1159: represnted
Typo: represented
func (t Time) UnixMilli() int64 {
return (t.unixSec())*1e3 + int64(t.nsec())/1e6
}
// UnixMicro returns t as a Unix time, the number of microseconds elapsed since
// January 1, 1970 UTC. The result is undefined if the Unix time in
// microseconds cannot be represnted by an int64 (a date before year -290307 or
// after year 294246). The result does not depend on the location associated
// with t.
func (t Time) UnixMicro() int64 {
return (t.unixSec())*1e6 + int64(t.nsec())/1e3
}
Nit: I'd suggest to move these above (Time).UnixNano, so the Unix* methods appear in increasing order of magnitude, i.e. UnixMilli, UnixMicro, UnixNano.
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Conrad Irwin.
Conrad Irwin uploaded patch set #7 to this change.
time: add Time.Unix{Milli,Micro} and to-Time helpers UnixMicro, UnixMilli
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 68 insertions(+), 0 deletions(-)
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Tobias Klauser, Conrad Irwin.
3 comments:
Patchset:
Updated, thanks Tobias!
File src/time/time.go:
Patch Set #6, Line 1159: represnted
Typo: represented
Done
func (t Time) UnixMilli() int64 {
return (t.unixSec())*1e3 + int64(t.nsec())/1e6
}
// UnixMicro returns t as a Unix time, the number of microseconds elapsed since
// January 1, 1970 UTC. The result is undefined if the Unix time in
// microseconds cannot be represnted by an int64 (a date before year -290307 or
// after year 294246). The result does not depend on the location associated
// with t.
func (t Time) UnixMicro() int64 {
return (t.unixSec())*1e6 + int64(t.nsec())/1e3
}
Nit: I'd suggest to move these above (Time). […]
Done
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Tobias Klauser, Conrad Irwin.
Patch set 7:Run-TryBot +1Code-Review +2
1 comment:
Patchset:
Thank you Conrad, thank you Tobias!
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.
Emmanuel Odeke submitted this change.
time: add Time.Unix{Milli,Micro} and to-Time helpers UnixMicro, UnixMilli
Adds helper functions for users working with other systems which
represent time in milliseconds or microseconds since the Unix epoch.
Fixes #44196
Change-Id: Ibc4490b52ddec94ebd0c692cb7b52a33e4536759
Reviewed-on: https://go-review.googlesource.com/c/go/+/293349
Reviewed-by: Emmanuel Odeke <emma...@orijtech.com>
Reviewed-by: Ian Lance Taylor <ia...@golang.org>
Run-TryBot: Emmanuel Odeke <emma...@orijtech.com>
TryBot-Result: Go Bot <go...@golang.org>
---
M src/time/time.go
M src/time/time_test.go
2 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/src/time/time.go b/src/time/time.go
index 841f989..cd756bb 100644
--- a/src/time/time.go
+++ b/src/time/time.go
@@ -1135,6 +1135,24 @@
return t.unixSec()
}
+// UnixMilli returns t as a Unix time, the number of milliseconds elapsed since
+// January 1, 1970 UTC. The result is undefined if the Unix time in
+// milliseconds cannot be represented by an int64 (a date more than 292 million
+// years before or after 1970). The result does not depend on the
+// location associated with t.
+func (t Time) UnixMilli() int64 {
+ return t.unixSec()*1e3 + int64(t.nsec())/1e6
+}
+
+// UnixMicro returns t as a Unix time, the number of microseconds elapsed since
+// January 1, 1970 UTC. The result is undefined if the Unix time in
+// microseconds cannot be represented by an int64 (a date before year -290307 or
+// after year 294246). The result does not depend on the location associated
+// with t.
+func (t Time) UnixMicro() int64 {
+ return t.unixSec()*1e6 + int64(t.nsec())/1e3
+}
+
// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
// since January 1, 1970 UTC. The result is undefined if the Unix time
// in nanoseconds cannot be represented by an int64 (a date before the year
@@ -1309,6 +1327,18 @@
return unixTime(sec, int32(nsec))
}
+// UnixMilli returns the local Time corresponding to the given Unix time,
+// msec milliseconds since January 1, 1970 UTC.
+func UnixMilli(msec int64) Time {
+ return Unix(msec/1e3, (msec%1e3)*1e6)
+}
+
+// UnixMicro returns the local Time corresponding to the given Unix time,
+// usec milliseconds since January 1, 1970 UTC.
+func UnixMicro(usec int64) Time {
+ return Unix(usec/1e6, (usec%1e6)*1e3)
+}
+
// IsDST reports whether the time in the configured location is in Daylight Savings Time.
func (t *Time) IsDST() bool {
_, _, _, _, isDST := t.loc.lookup(t.Unix())
diff --git a/src/time/time_test.go b/src/time/time_test.go
index 3a58bfe..f272bbd 100644
--- a/src/time/time_test.go
+++ b/src/time/time_test.go
@@ -202,6 +202,28 @@
}
}
+func TestUnixMilli(t *testing.T) {
+ f := func(msec int64) bool {
+ t := UnixMilli(msec)
+ return t.UnixMilli() == msec
+ }
+ cfg := &quick.Config{MaxCount: 10000}
+ if err := quick.Check(f, cfg); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestUnixMicro(t *testing.T) {
+ f := func(usec int64) bool {
+ t := UnixMicro(usec)
+ return t.UnixMicro() == usec
+ }
+ cfg := &quick.Config{MaxCount: 10000}
+ if err := quick.Check(f, cfg); err != nil {
+ t.Fatal(err)
+ }
+}
+
// The time routines provide no way to get absolute time
// (seconds since zero), but we need it to compute the right
// answer for bizarre roundings like "to the nearest 3 ns".
@@ -959,6 +981,8 @@
}{
{0, `time.Now()`, func() { t = Now() }},
{0, `time.Now().UnixNano()`, func() { u = Now().UnixNano() }},
+ {0, `time.Now().UnixMilli()`, func() { u = Now().UnixMilli() }},
+ {0, `time.Now().UnixMicro()`, func() { u = Now().UnixMicro() }},
}
func TestCountMallocs(t *testing.T) {
@@ -1249,6 +1273,8 @@
{"Unix", func(t1, t2 Time) bool { return t1.Unix() == t2.Unix() }},
{"UnixNano", func(t1, t2 Time) bool { return t1.UnixNano() == t2.UnixNano() }},
+ {"UnixMilli", func(t1, t2 Time) bool { return t1.UnixMilli() == t2.UnixMilli() }},
+ {"UnixMicro", func(t1, t2 Time) bool { return t1.UnixMicro() == t2.UnixMicro() }},
{"MarshalBinary", func(t1, t2 Time) bool {
a1, b1 := t1.MarshalBinary()
@@ -1301,6 +1327,18 @@
}
}
+func BenchmarkNowUnixMilli(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ u = Now().UnixMilli()
+ }
+}
+
+func BenchmarkNowUnixMicro(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ u = Now().UnixMicro()
+ }
+}
+
func BenchmarkFormat(b *testing.B) {
t := Unix(1265346057, 0)
for i := 0; i < b.N; i++ {
To view, visit change 293349. To unsubscribe, or for help writing mail filters, visit settings.