Jak parsować znacznik czasu unixa na czas

126

Próbuję przeanalizować sygnaturę czasową systemu Unix, ale pojawia się błąd poza zakresem. To nie ma dla mnie sensu, ponieważ układ jest poprawny (jak w dokumentacji Go):

package main

import "fmt"
import "time"

func main() {
    tm, err := time.Parse("1136239445", "1405544146")
    if err != nil{
        panic(err)
    }

    fmt.Println(tm)
}

Plac zabaw

Hej
źródło

Odpowiedzi:

239

time.ParseFunkcja nie robić sygnatury czasowe Unix. Zamiast tego możesz użyć strconv.ParseIntdo przeanalizowania ciągu int64i utworzenia znacznika czasu za pomocą time.Unix:

package main

import (
    "fmt"
    "time"
    "strconv"
)

func main() {
    i, err := strconv.ParseInt("1405544146", 10, 64)
    if err != nil {
        panic(err)
    }
    tm := time.Unix(i, 0)
    fmt.Println(tm)
}

Wynik:

2014-07-16 20:55:46 +0000 UTC

Plac zabaw: http://play.golang.org/p/v_j6UIro7a

Edytować:

Zmieniono z strconv.Atoina, strconv.ParseIntaby uniknąć przepełnienia int w systemach 32-bitowych.

ANisus
źródło
1
Masz jakiś pomysł, dlaczego nie ma takiego odniesienia w dokumentach? Podają nawet układ unix timestap jako przykład układu.
cześć
Wydaje mi się, że dzieje się tak, ponieważ znacznik czasu unixa nie wymaga analizy, ponieważ nie jest reprezentacją tekstową, ale raczej całkowitą reprezentacją czasu. Właśnie zdarzyło Ci się mieć łańcuch reprezentujący wartość całkowitą. A wzmianka o 1136239445 w dokumentacji ma prawdopodobnie na celu wyjaśnienie, jaki dokładny znacznik czasu ma być używany jako czas odniesienia, a nie, że ma być używany jako układ.
ANisus,
4
Czy nie byłoby lepiej użyć strconv.ParseUintzamiast tego, ponieważ liczby ujemne i tak nie mają sensu?
Atmocreations
6
@Atmocreations: func Unix(sec int64, nsec int64) Timeodbiera int64wartości. Również liczby ujemne dla sekund mają sens - opisują daty sprzed 1970 roku! :) Jeśli chodzi o nsecwartości ujemne, oznacza to, że z sekund można usunąć tyle nanosekund.
ANisus
1
Chcę tylko daty i godziny „2014-07-16 20:55:46”. Jak można to osiągnąć?
karthik
14

Możesz bezpośrednio użyć funkcji time.Unix czasu, która konwertuje uniksowy znacznik czasu na UTC

package main

import (
  "fmt"
  "time"
)


func main() {
    unixTimeUTC:=time.Unix(1405544146, 0) //gives unix time stamp in utc 

    unitTimeInRFC3339 :=unixTimeUTC.Format(time.RFC3339) // converts utc time to RFC3339 format

    fmt.Println("unix time stamp in UTC :--->",unixTimeUTC)
    fmt.Println("unix time stamp in unitTimeInRFC3339 format :->",unitTimeInRFC3339)
}

Wynik

unix time stamp in UTC :---> 2014-07-16 20:55:46 +0000 UTC
unix time stamp in unitTimeInRFC3339 format :----> 2014-07-16T20:55:46Z

Sprawdź w Go Playground: https://play.golang.org/p/5FtRdnkxAd

negi Yogi
źródło
4

Udostępniam kilka funkcji, które stworzyłem dla dat:

Zwróć uwagę, że chciałem uzyskać czas dla określonej lokalizacji (nie tylko czas UTC). Jeśli chcesz mieć czas UTC, po prostu usuń zmienną loc i wywołanie funkcji .In (loc).

func GetTimeStamp() string {
     loc, _ := time.LoadLocation("America/Los_Angeles")
     t := time.Now().In(loc)
     return t.Format("20060102150405")
}
func GetTodaysDate() string {
    loc, _ := time.LoadLocation("America/Los_Angeles")
    current_time := time.Now().In(loc)
    return current_time.Format("2006-01-02")
}

func GetTodaysDateTime() string {
    loc, _ := time.LoadLocation("America/Los_Angeles")
    current_time := time.Now().In(loc)
    return current_time.Format("2006-01-02 15:04:05")
}

func GetTodaysDateTimeFormatted() string {
    loc, _ := time.LoadLocation("America/Los_Angeles")
    current_time := time.Now().In(loc)
    return current_time.Format("Jan 2, 2006 at 3:04 PM")
}

func GetTimeStampFromDate(dtformat string) string {
    form := "Jan 2, 2006 at 3:04 PM"
    t2, _ := time.Parse(form, dtformat)
    return t2.Format("20060102150405")
}
Adi
źródło
Usunięcie .In(loc)dało mi trochę czasu -0400 EDT. Zastąpienie go .In(time.UTC)dało mi czas w UTC.
NatoBoram,
3

Zgodnie z dokumentacją go , Unix zwraca czas lokalny.

Unix zwraca lokalny czas odpowiadający podanemu czasowi uniksowemu

Oznacza to, że dane wyjściowe zależą od maszyny, na której działa twój kod, która najczęściej jest tym, czego potrzebujesz, ale czasami możesz chcieć mieć wartość w UTC.

Aby to zrobić, dostosowałem fragment kodu tak, aby zwracał czas w UTC:

i, err := strconv.ParseInt("1405544146", 10, 64)
if err != nil {
    panic(err)
}
tm := time.Unix(i, 0)
fmt.Println(tm.UTC())

To drukuje na moim komputerze (w CEST)

2014-07-16 20:55:46 +0000 UTC
Thib-o
źródło
0

Robię dużo rejestrowania, gdzie znaczniki czasu to float64 i używam tej funkcji, aby uzyskać znaczniki czasu jako ciąg:

func dateFormat(layout string, d float64) string{
    intTime := int64(d)
    t := time.Unix(intTime, 0)
    if layout == "" {
        layout = "2006-01-02 15:04:05"
    }
    return t.Format(layout)
}
Saxasmu
źródło
-6

Po prostu wykorzystaj czas

przykład:

package main

import (
    "fmt"
    "time"
)

func main() {
    fromString := "Wed, 6 Sep 2017 10:43:01 +0300"
    t, e := time.Parse("Mon, _2 Jan 2006 15:04:05 -0700", fromString)
    if e != nil {
        fmt.Printf("err: %s\n", e)
    }
    fmt.Printf("UTC time: %v\n", t.UTC())
}

Przykład roboczy na play.golang.org .

okhrypko
źródło
2
Pytanie określa uniksowy znacznik czasu. Ta odpowiedź nie dotyczy tego aspektu.
t3h2mas