Home  >  Article  >  Backend Development  >  Convert Chrome timestamps in Go

Convert Chrome timestamps in Go

WBOY
WBOYforward
2024-02-06 11:03:03800browse

在 Go 中转换 Chrome 时间戳

Question content

I'm trying to convert a timestamp from a local Chrome sqlite database to local time using Go. I know these timestamps are microseconds starting from 1601/01/01.

Checking the values ​​of lastVisitTime that I get in the following program on this Chrome Timestamp Conversion website, I seem to be retrieving them from the database correctly.

<code>package main

import (
    "database/sql"
    "fmt"
    "time"

    _ "github.com/mattn/go-sqlite3"

    "github.com/local_library/comp"
)

var (
    dbPath           = comp.Expanduser("~/Library/Application Support/Google/Chrome/Default/History")
    chromeEpochStart = time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC)
)

const (
    driverName = "sqlite3"
    tmpPath    = "/tmp/History"
    query      = `
SELECT
    last_visit_time
FROM 
    urls
ORDER BY
    last_visit_time DESC
LIMIT 5
`
)

func main() {
    // Copy to tmp to unlock
    err := comp.Copy(dbPath, tmpPath)
    comp.MustBeNil(err)

    db, err := sql.Open(driverName, tmpPath)
    comp.MustBeNil(err)
    rows, err := db.Query(query)
    comp.MustBeNil(err)
    for rows.Next() {
        var lastVisitTime int64
        rows.Scan(&lastVisitTime)
        d := time.Duration(time.Microsecond * time.Duration(lastVisitTime))
        t := chromeEpochStart.Add(d)
        fmt.Println(t, lastVisitTime)
    }

    err = rows.Close()
    comp.MustBeNil(err)
    err = rows.Err()
    comp.MustBeNil(err)
}
</code>

But for some reason my .Add(d) sets the time to 1601 before, which I've never seen before.

1439-07-05 20:00:21.462742384 +0000 UTC 13350512095172294
1439-07-05 19:58:20.377916384 +0000 UTC 13350511974087468
1439-07-05 19:57:58.539932384 +0000 UTC 13350511952249484
1439-07-05 19:57:48.539540384 +0000 UTC 13350511942249092
1439-07-05 19:52:09.587445384 +0000 UTC 13350511603296997

What's going on here, and more importantly, how do I do this correctly?


Correct answer


Thanks Peter's comment pointed out the overflow in my original code and I found a different approach.

If you convert the Chrome start date to UnixMicro(), you get a negative offset from the regular epoch time:

<code>chromeMicroOffset := time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC).UnixMicro()
fmt.Println(chromeMicroOffset)
</code>
-11644473600000000

Add these to the database values ​​and convert them to nanoseconds in time.Unix() to get the correct UTC time:

<code>microFromEpoch := chromeMicroOffset + lastVisitTime
t := time.Unix(0, microFromEpoch*1000)
</code>

Full example of conversion to Pacific Time:

<code>package main

import (
    "fmt"
    "time"
)

var (
    chromeMicroOffset = time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC).UnixMicro()
)

func main() {
    chromeTimestamp := int64(13350516239099543)

    microFromEpoch := chromeMicroOffset + chromeTimestamp
    t := time.Unix(0, microFromEpoch*1000)
    loc, err := time.LoadLocation("America/Los_Angeles")
    if err != nil {
        panic(err)
    }
    fmt.Println(t.In(loc))
}
</code>
2024-01-23 12:43:59.099543 -0800 PST

The above is the detailed content of Convert Chrome timestamps in Go. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete