Как разобрать временную метку unix на time.Time

Я пытаюсь разобрать метку времени Unix, но получаю ошибку вне допустимого диапазона. Для меня это не имеет смысла, потому что макет правильный (как в документации Go):

package main

import "fmt"
import "time"

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

    fmt.Println(tm)
}

Детская площадка


person hey    schedule 28.07.2014    source источник


Ответы (5)


Функция time.Parse не делает отметок времени Unix. Вместо этого вы можете использовать strconv.ParseInt для синтаксического анализа строки до int64 и создания отметки времени с 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)
}

Вывод:

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

Площадка: http://play.golang.org/p/v_j6UIro7a

Изменить:

Изменено с strconv.Atoi на strconv.ParseInt, чтобы избежать переполнения int в 32-битных системах.

person ANisus    schedule 28.07.2014
comment
Есть идеи, почему в документах нет такой ссылки? Они даже приводят в качестве примера макет временной метки unix. - person hey; 28.07.2014
comment
Я предполагаю, что это потому, что временная метка unix не требует синтаксического анализа, поскольку это не текстовое представление, а целочисленное представление времени. У вас просто оказалось строковое представление целочисленного значения. И упоминание 1136239445 в документации, вероятно, просто для того, чтобы прояснить, какая точная временная метка должна использоваться в качестве эталонного времени, а не для того, чтобы ее использовать в качестве макета. - person ANisus; 28.07.2014
comment
Не лучше было бы вместо этого использовать strconv.ParseUint, поскольку отрицательные числа в любом случае не имеют смысла? - person Atmocreations; 25.04.2016
comment
@Atmocreations: func Unix(sec int64, nsec int64) Time получает int64 значений. Кроме того, отрицательные числа для секунд имеют смысл - они описывают даты до 1970 года! :) Что касается nsec, отрицательные значения означают удаление этого количества наносекунд из секунд. - person ANisus; 26.04.2016
comment
Я хочу только дату и время, как 2014-07-16 20:55:46 как это могло быть достигнуто? - person karthik; 07.11.2016

Вы можете напрямую использовать функцию времени time.Unix, которая преобразует метку времени unix в 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)
}

Выход

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

Отметьте Go Playground: https://play.golang.org/p/5FtRdnkxAd

person negi Yogi    schedule 06.12.2017
comment
time.Unix() задокументирован для возврата местного времени. Следовательно, unixTimeUTC в этом ответе не всегда указывает время в часовом поясе UTC. Только когда местный часовой пояс соответствует UTC. - person Dr. Jan-Philip Gehrcke; 17.02.2021
comment
@ Доктор Ян-Филип Герке: Интересно, имеет ли это значение в конечном итоге. time.Unix() проанализирует время на время в некотором часовом поясе (с информацией о часовом поясе). Затем его можно повторно использовать в любом месте (например, преобразовать в заданную TZ). Правда, в этом случае имя переменной может быть неудачным. - person WoJ; 11.07.2021

Совместное использование нескольких функций, которые я создал для свиданий:

Обратите внимание, что я хотел узнать время для определенного места (а не только время UTC). Если вам нужно время в формате UTC, просто удалите переменную loc и вызов функции .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")
}
person Adi    schedule 14.12.2017
comment
Удаление .In(loc) дало мне время в -0400 EDT. Замена на .In(time.UTC) дала мне время в UTC. - person NatoBoram; 16.07.2019

Согласно документации go, Unix возвращает местное время.

Unix возвращает местное время, соответствующее заданному времени Unix.

Это означает, что вывод будет зависеть от машины, на которой работает ваш код, что чаще всего является тем, что вам нужно, но иногда вам может потребоваться значение в формате UTC.

Для этого я адаптировал фрагмент, чтобы он возвращал время в формате UTC:

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

Это напечатано на моей машине (в CEST)

2014-07-16 20:55:46 +0000 UTC
person Thib-o    schedule 24.09.2018

Я много веду журналы, где метки времени - float64, и использую эту функцию, чтобы получить метки времени в виде строки:

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)
}
person Saxasmu    schedule 23.07.2020