Reputation: 8733
How can I get Unix time in Go in milliseconds?
I have the following function:
func makeTimestamp() int64 {
return time.Now().UnixNano() % 1e6 / 1e3
}
I need less precision and only want milliseconds.
Upvotes: 141
Views: 232134
Reputation: 99254
As of go v1.17, the time
package added UnixMicro()
and UnixMilli()
, so the correct answer would be: time.Now().UnixMilli()
Just divide it:
func makeTimestamp() int64 {
return time.Now().UnixNano() / 1e6
}
1e6
, i.e. 1 000 000, is the number of nanoseconds in a millisecond.
Here is an example that you can compile and run to see the output
package main
import (
"time"
"fmt"
)
func main() {
a := makeTimestamp()
fmt.Printf("%d \n", a)
}
func makeTimestamp() int64 {
return time.Now().UnixNano() / 1e6
}
Upvotes: 233
Reputation: 44787
How can I get Unix time in Go in milliseconds?
No more divisions from nanoseconds. Starting from Go 1.17 you can just use Time.UnixMilli
method directly:
// a deterministic date value
t := time.Date(2021, 7, 16, 0, 0, 0, 0, time.UTC)
m := t.UnixMilli()
fmt.Println(m) // 1626393600000
Playground: https://play.golang.org/p/JSExv5jw2ZW
Upvotes: 15
Reputation: 13878
At https://github.com/golang/go/issues/44196 randall77 suggested
time.Now().Sub(time.Unix(0,0)).Milliseconds()
which exploits the fact that Go's time.Duration
already have Milliseconds
method.
Upvotes: 5
Reputation: 184
Simple-read but precise solution would be:
func nowAsUnixMilliseconds(){
return time.Now().Round(time.Millisecond).UnixNano() / 1e6
}
This function:
P.S. I've run benchmarks with constant and composite dividers, they showed almost no difference, so feel free to use more readable or more language-strict solution.
Upvotes: 2
Reputation: 3880
Keep it simple.
func NowAsUnixMilli() int64 {
return time.Now().UnixNano() / 1e6
}
Upvotes: 71
Reputation: 541
I think it's better to round the time to milliseconds before the division.
func makeTimestamp() int64 {
return time.Now().Round(time.Millisecond).UnixNano() / (int64(time.Millisecond)/int64(time.Nanosecond))
}
Here is an example program:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(unixMilli(time.Unix(0, 123400000)))
fmt.Println(unixMilli(time.Unix(0, 123500000)))
m := makeTimestampMilli()
fmt.Println(m)
fmt.Println(time.Unix(m/1e3, (m%1e3)*int64(time.Millisecond)/int64(time.Nanosecond)))
}
func unixMilli(t time.Time) int64 {
return t.Round(time.Millisecond).UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond))
}
func makeTimestampMilli() int64 {
return unixMilli(time.Now())
}
The above program printed the result below on my machine:
123
124
1472313624305
2016-08-28 01:00:24.305 +0900 JST
Upvotes: 3
Reputation: 11469
As @Jono points out in @OneOfOne's answer, the correct answer should take into account the duration of a nanosecond. Eg:
func makeTimestamp() int64 {
return time.Now().UnixNano() / (int64(time.Millisecond)/int64(time.Nanosecond))
}
OneOfOne's answer works because time.Nanosecond
happens to be 1
, and dividing by 1 has no effect. I don't know enough about go to know how likely this is to change in the future, but for the strictly correct answer I would use this function, not OneOfOne's answer. I doubt there is any performance disadvantage as the compiler should be able to optimize this perfectly well.
See https://en.wikipedia.org/wiki/Dimensional_analysis
Another way of looking at this is that both time.Now().UnixNano()
and time.Millisecond
use the same units (Nanoseconds). As long as that is true, OneOfOne's answer should work perfectly well.
Upvotes: 69