Go / golang time.Now (). UnixNano () in Millisekunden konvertieren?

82

Wie kann ich Unix-Zeit in Go in Millisekunden erhalten?

Ich habe folgende Funktion:

func makeTimestamp() int64 {
    return time.Now().UnixNano() % 1e6 / 1e3
}

Ich brauche weniger Präzision und möchte nur Millisekunden.

mconlin
quelle

Antworten:

127

Teilen Sie es einfach:

func makeTimestamp() int64 {
    return time.Now().UnixNano() / int64(time.Millisecond)
}

Hier ist ein Beispiel, das Sie kompilieren und ausführen können, um die Ausgabe anzuzeigen

package main

import (
    "time"
    "fmt"
)

func main() {
    a := makeTimestamp()

    fmt.Printf("%d \n", a)
}

func makeTimestamp() int64 {
    return time.Now().UnixNano() / int64(time.Millisecond)
}
OneOfOne
quelle
39
Die obige Berechnung ist nicht wirklich sinnvoll. Sie teilen Nanosekunden nicht durch Millisekunden. Es ist der Fall, dass Golang Zeiten bis zur Nanosekunde darstellt und die Konstante 'Millisekunde' 1.000.000 beträgt. Mathematisch gesehen sollte die Berechnung sein : time.Now().UnixNano() * (time.Nanosecond / time.Millisecond). Es ist jedoch am besten, die Reihenfolge wegen der Ganzzahldivision zu ändern:time.Nanosecond * time.Now().UnixNano() / time.Millisecond
Jonno
4
Dank dafür. Sie können sich gerne auf diese Garantie verlassen, aber dies ist tatsächlich ein Y2K-Fehler. Es kann irgendwann in der Zukunft brechen. Warum die falsche mathematische Darstellung wählen?
Jonno
2
Sie sind beliebige Konstanten. Sie können sich in Zukunft ändern. Das Zeitpaket "arbeitet" derzeit mit einer Genauigkeit von Nanosekunden, aber dies ist eine willkürliche Wahl, die zum Einstellen der Zeit führt. Millisekunde = 1.000.000. Beachten Sie, dass time.Milisecond auch in derselben Datei, auf die Sie verwiesen haben, auf 1000 * Mikrosekunden eingestellt ist, da dies mathematisch gesehen das sein sollte, was es darstellen sollte. Ich gehe offline - Ich hoffe, meine Erklärung hilft
Jonno
10
-1 Das ist einfach falsch. Ihre Einheiten summieren sich nicht. Schlagen Sie die Dimensionsanalyse aus der Physik nach. Ihr Ergebnis repräsentiert keine Zeit.
Kugel
7
Schnelle Antwort für vielbeschäftigte Menschen. Schauen Sie sich https://gobyexample.com/epoch
honzajde
63

Wie @Jono in der Antwort von @ OneOfOne ausführt, sollte die richtige Antwort die Dauer einer Nanosekunde berücksichtigen. Z.B:

func makeTimestamp() int64 {
    return time.Now().UnixNano() / (int64(time.Millisecond)/int64(time.Nanosecond))
}

Die Antwort von OneOfOne funktioniert, weil time.Nanoseconddies der Fall 1ist und das Teilen durch 1 keine Auswirkung hat. Ich weiß nicht genug darüber, wie wahrscheinlich es ist, dass sich dies in Zukunft ändert, aber für die streng korrekte Antwort würde ich diese Funktion verwenden, nicht die Antwort von OneOfOne. Ich bezweifle, dass es einen Leistungsnachteil gibt, da der Compiler dies perfekt optimieren sollte.

Siehe https://en.wikipedia.org/wiki/Dimensional_analysis

Eine andere Sichtweise ist, dass beide time.Now().UnixNano()und time.Milliseconddieselben Einheiten (Nanosekunden) verwenden. Solange dies zutrifft, sollte die Antwort von OneOfOne einwandfrei funktionieren.

Björn Roche
quelle
4
Der Wert von .UnixNano()wird immer die Zeit in Nanosekunden sein, time.Millisecondwird immer der Wert für gut sein, Sie haben es erraten, eine Millisekunde. Selbst wenn sich der Wert der Konstante aus irgendeinem idiotischen Grund ändert, gibt die Division von UnixNano durch Millisekunde immer den Wert in Millisekunden zurück.
OneOfOne
9
Die Einheiten von Unix.Nano sind nicht in Frage; noch ist der Wert der Zeit. Millisekunde. Was ist in Frage ist die Einheit der time.Millisecond. Es wird zufällig in Nanosekunden definiert, weshalb Ihre Antwort funktioniert. Wenn time.Milliseconds in anderen Einheiten (z. B. Mikrosekunden) gemessen würde, würde die von Ihnen angegebene Antwort nicht funktionieren.
Björn Roche
2
@BjornRoche Ich bin etwas spät zu dieser Party, aber wäre die richtige Antwort nicht (int64(time.Now().UnixNano() / int64(time.Nanosecond))/int64(time.Millisecond)? Die Dimensionsanalyse ns/(ms/ns)kehrt zurück ns^2/ms. Ihre Antwort funktioniert auch, weil time.Nanosecond=1, aber die Einheiten sind aus ...
Der Puma
1
@thepuma Es ist eine Weile her, also sehe ich das vielleicht falsch oder missverstehe dich, aber ns / (ms / ns) entspricht ns ^ 2 / ms, also sollten beide Antworten funktionieren.
Björn Roche
Diese Antwort ist richtig, da beim Ausführen dies das gleiche Ergebnis anzeigt wie beim Konvertieren mit dem Online-Konverter unitconverters.net/prefixes/nano-to-milli.htm
user666
55

Halte es einfach.

func NowAsUnixMilli() int64 {
    return time.Now().UnixNano() / 1e6
}
Stratovarius
quelle
2

Ich denke, es ist besser, die Zeit auf Millisekunden vor der Teilung zu runden.

func makeTimestamp() int64 {
    return time.Now().Round(time.Millisecond).UnixNano() / (int64(time.Millisecond)/int64(time.Nanosecond))
}

Hier ist ein Beispielprogramm:

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())
}

Das obige Programm hat das folgende Ergebnis auf meinem Computer gedruckt:

123
124
1472313624305
2016-08-28 01:00:24.305 +0900 JST
hnakamur
quelle
Sie haben vergessen zu erwähnen, warum es Ihrer Meinung nach besser ist, die Zeit auf Millisekunden zu runden.
Gurpartap Singh
1

Einfach zu lesende, aber präzise Lösung wäre:

func nowAsUnixMilliseconds(){
    return time.Now().Round(time.Millisecond).UnixNano() / 1e6
}

Diese Funktion:

  1. Rundet den Wert korrekt auf die nächste Millisekunde (vergleiche mit der Ganzzahldivision: Es wird nur der Dezimalteil des resultierenden Werts verworfen).
  2. Taucht nicht in Go-Besonderheiten der Zeit ein. Durationszwang - da eine numerische Konstante verwendet wird, die den absoluten Millisekunden / Nanosekunden-Teiler darstellt.

PS Ich habe Benchmarks mit konstanten und zusammengesetzten Teilern durchgeführt. Sie zeigten fast keinen Unterschied. Sie können also eine besser lesbare oder sprachlich strengere Lösung verwenden.

Liubov
quelle
Wenn Sie die korrekte Unix-Zeit in Millisekunden (Millisekunden seit der Epoche) wissen möchten, sollten Sie Round () nicht verwenden, da dies die Hälfte der Zeit aufrundet und Ihr Ergebnis dann eine Millisekunde enthält, die noch nicht vollständig verstrichen ist.
Torbenl
Vielen Dank für einen Hinweis, @torbenl - dies kann für die meisten Systeme wichtig sein (meins ist ein Ausschluss, diese Zeit wird nur für den Verlauf gespeichert).
Liubov