Die Behandlung von Zeit ist ziemlich komplex. Häufige falsche Annahmen über die Zeit sind folgende.
- Ein Tag besteht aus 24 Stunden.
- Eine Stunde enthält 60 Minuten.
- Eine Woche besteht aus sieben Tagen.
- Ein Jahr umfasst 365 Tage.
Beispiel: 1 besagt, dass das Hinzufügen von 24 Stunden zu einem bestimmten Zeitpunkt nicht immer zu einem neuen Kalendertag führt.
Deshalb sollte bei der Behandlung von Zeit immer das "time"
Paket verwendet werden, da es hilft, diese falschen Annahmen auf sicherere und genauere Weise zu behandeln.
Verwendung von time.Time
zur Darstellung von Momentaufnahmen
Bei der Arbeit mit Momentaufnahmen sollte time.Time
und seine Methoden zur Vergleichung, Addition oder Subtraktion von Zeit verwendet werden.
Nicht empfohlen:
func isActive(now, start, stop int) bool {
return start <= now && now < stop
}
Empfohlen:
func isActive(now, start, stop time.Time) bool {
return (start.Before(now) || start.Equal(now)) && now.Before(stop)
}
Verwendung von time.Duration
zur Darstellung von Zeitdauern
Bei der Bearbeitung von Zeitdauern sollte time.Duration
verwendet werden.
Nicht empfohlen:
func poll(delay int) {
for {
// ...
time.Sleep(time.Duration(delay) * time.Millisecond)
}
}
poll(10) // Ist es in Sekunden oder Millisekunden?
Empfohlen:
func poll(delay time.Duration) {
for {
// ...
time.Sleep(delay)
}
}
poll(10*time.Second)
Zurück zum ersten Beispiel: Wenn 24 Stunden zu einer Momentaufnahme hinzugefügt werden, hängt die verwendete Methode von der Absicht ab. Wenn wir denselben Zeitpunkt am nächsten Kalendertag möchten (also am Tag nach dem aktuellen Tag), sollten wir Time.AddDate
verwenden. Wenn wir jedoch sicherstellen möchten, dass ein bestimmter Moment 24 Stunden später als der vorherige ist, sollten wir Time.Add
verwenden.
neuerTag := t.AddDate(0 /* Jahre */, 0 /* Monate */, 1 /* Tage */)
vielleichtNeuerTag := t.Add(24 * time.Hour)
Verwendung von time.Time
und time.Duration
mit externen Systemen
Verwenden Sie bei Interaktionen mit externen Systemen, wann immer möglich, time.Duration
und time.Time
, zum Beispiel:
- Befehlszeilenoptionen:
flag
unterstützttime.Duration
übertime.ParseDuration
. - JSON:
encoding/json
unterstützt die Codierung vontime.Time
in einen RFC 3339 String mit seiner MethodeUnmarshalJSON
. - SQL:
database/sql
unterstützt die Konvertierung vonDATETIME
oderTIMESTAMP
Spalten intime.Time
und gibt zurück, ob der zugrunde liegende Treiber dies unterstützt. - YAML:
gopkg.in/yaml.v2
unterstützt die Verwendung vontime.Time
als einen RFC 3339 String undtime.Duration
durchtime.ParseDuration
.
Wenn time.Duration
in diesen Interaktionen nicht verwendet werden kann, verwenden Sie int
oder float64
und fügen Sie die Einheit in den Feldnamen ein.
Zum Beispiel, da encoding/json
time.Duration
nicht unterstützt, wird die Einheit im Feldnamen enthalten.
Nicht empfohlen:
// {"interval": 2}
type Config struct {
Interval int `json:"interval"`
}
Empfohlen:
// {"intervalMillis": 2000}
type Config struct {
IntervalMillis int `json:"intervalMillis"`
}
Wenn time.Time
in diesen Interaktionen nicht verwendet werden kann, verwenden Sie, sofern nicht anders vereinbart, string
und formatieren Sie Zeitstempel gemäß RFC 3339. Standardmäßig verwendet Time.UnmarshalText
dieses Format und kann in Time.Format
und time.Parse
durch time.RFC3339
verwendet werden.
Obwohl dies kein praktisches Problem darstellt, beachten Sie bitte, dass das Paket "time"
das Parsen von Schaltsekunden-Zeitstempeln (8728) nicht unterstützt und keine Schaltsekunden bei Berechnungen berücksichtigt (15190). Wenn Sie zwei Zeitpunkte vergleichen, wird die Differenz keine Schaltsekunden enthalten, die zwischen diesen beiden Zeitpunkten aufgetreten sein könnten.