Marshalling time.Time to unix timestamp

unix time now
golang json unix timestamp
unix timestamp milliseconds
rfc3339 timestamp
timestamp format
golang json time
epoch converter 2019
utc converter

I have a struct like so

type log struct {
    [...]
    Timestamp timestamp `json:"timestamp"`
}

and I want to have the Timestamp as unix timestamp instead of whatever go does by default (2018-09-21T19:31:03.291Z)

I've tried creating a custom type for that like this:

type timestamp struct {
    time.Time
}

func (t timestamp) MarshalJSON() ([]byte, error) {
    return []byte(strconv.FormatInt(time.Time(t.Time).Unix(), 10)), nil
}

func (t *timestamp) UnmarshalJSON(data []byte) error {
    i, err := strconv.ParseInt(string(data[:]), 10, 64)
    if err != nil {
        return err
    }
    t = &timestamp{
        time.Unix(i, 0),
    }
    return nil
}

but I'm always getting the error can not unmarshal timestamp into *main.timestamp when trying to read from the database.

for iter.Scan(&message.Text, &message.Timestamp) {

    userlogResult.Messages = append(userlogResult.Messages, message)
}
if err := iter.Close(); err != nil {
    log.Error(err)
}

It can't unmarshall the Timestamp here. https://github.com/gocql/gocql/blob/799fb0373110eaa4e2e71dd32a9b5903f80dca8f/helpers.go#L30 the issue is that it doesn't use the Unmarshall functions.

Edit: I've answered my own question.

I think your code is ok - apart from the code in your unmarshal. You don't show the code where you are Marshalling/Unmarshalling which is where the actual error is.

I have it working on the playground. Golang Playground

Instead of this (which changes the pointer)

t = &timestamp{
  time.Unix(i, 0),
}

Change the value

t.Time = time.Unix(i,0)

Main function to use your structs

fmt.Println("First Log...")
l := log{Timestamp: timestamp{time.Now()}}
fmt.Println(l)

buf, err := json.Marshal(l)
if err != nil {
    panic(err)
}
fmt.Println("Marshalled to JSON...")
fmt.Printf("%s\n", buf)

var logCopy log
if err := json.Unmarshal(buf, &logCopy); err != nil {
    panic(err)
}
fmt.Println("UnMarshalled from JSON...")
fmt.Println(logCopy)

json - Marshalling time.Time to unix timestamp, I think your code is ok - apart from the code in your unmarshal. You don't show the code where you are Marshalling/Unmarshalling which is  The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of seconds that have elapsed since January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). Literally speaking the epoch is Unix time 0 (midnight 1/1/1970), but 'epoch' is often used as a synonym for Unix time.

here when assigning &timestamp{..} to t it is changing the pointer instead the value it is pointed to has to be chaged as follows

func (t *timestamp) UnmarshalJSON(data []byte) error {
    i, err := strconv.ParseInt(string(data[:]), 10, 64)
    if err != nil {
        return err
    }
    *t = timestamp{
        time.Unix(i, 0),
    }
    return nil
}

Please find code here

Edit

Since you are failing to unmarshall when reading from Database it is not because of json.unmarshalling you have to implement sql.Scanner if you are using sql

Please find the details here => sql.Scanner

Handling Unix Timestamps in JSON, A unix timestamp is an integer indicating the number of seconds since Time // MarshalJSON is used to convert the timestamp to JSON func (t  The unix time stamp is a way to track time as a running total of seconds. This count starts at the Unix Epoch on January 1st, 1970 at UTC. Therefore, the unix time stamp is merely the number of seconds between a particular date and the Unix Epoch. It should also be pointed out (thanks to the comments from visitors to this site) that this

Alright after confusing a lot of people here (sorry) and myself I've found a solution.

The marshalling to json works now only need to fix the gocql compatiblity like this:

var ts time.Time
for iter.Scan(&message.Text, &ts) {
    message.Timestamp = timestamp{ts}

    userlogResult.Messages = append(userlogResult.Messages, message)
}

Marshalling time.Time to unix timestamp - json - html, Time).Unix(), 10)), nil } func (t *timestamp) UnmarshalJSON(data []byte) error { i, The marshalling to json works now only need to fix the gocql compatiblity like  Contains primitives for marshaling/unmarshaling Unix timestamp/epoch to/from build-in time.Time type in JSON go golang serialization json time date unix-timestamp deserialization timestamp epoch epoch-time

Unix Time Stamp, Epoch and unix timestamp converter for developers. Date and time function syntax reference for various programming languages. Another option for marshalling with the timestamp field set automatically. The UNIX time is conventionally seconds since January 1, 1970. UTC time is used, and leap seconds are excluded.

Marshalling `time.Time` as a number · Issue #83 · guregu/dynamo , Time values in Dynamo as numbers (unix timestamps) so I can use then as and Unmarshaller implementation: // Timestamp represents a time. But for some unknown reason it's just way too complex to convert a millisecond resolution Unix timestamp to time.Time. The built-in time.Unix() function only supports second and nanosecond precision. This means that you either have to multiply the millis to nanoseconds or split them into seconds and nanoseconds.

Golang unmarshal JSON epoch in milliseconds from string to time , Golang gist for unmarshalling JSON containing an epoch timestamp with the value in milliseconds, stored as a string: {"timestamp":  There is a standard way of doing those conversions in C, which is through the functions defined in <time.h>. This API being standard, you can test it in your computer. Recent versions of the avr-libc support this: see time.h in avr-libc. These functions can handle local time if you provide a function implementing the DST rules: see set_dst

Comments
  • Please provide the code for json where you are unmarshalling the data into timestamp.
  • The error says error on "Unmarshal" not on marshal , you need to implement Unmarshaller for unmarshal to work
  • I'm using echo's context.JSON for that here is the code: github.com/labstack/echo/blob/master/context.go#L406 As for @SarathSadasivanPillai true I didn't notice that. I will try that
  • @SarathSadasivanPillai I've added the UnmarshalJSON method but sadly the error stays
  • You defined custom marshaling / unmarshaling for the timestamp type, but you don't use that in log. So either use timestamp in log, or define custom marshaling / unmarshaling on the log type.
  • Hmm yes, I have a similar working version on the playground now aswell. Okay so I know that code is good, but I'm still having issues in my program. I don't marshall it myself, I'm not even sure why the unmarshal error is thrown, the actual point where it is marshalled is here: github.com/labstack/echo/blob/master/context.go#L406 My code is just return c.JSON(http.StatusOK, userlogResult)
  • This wouldn't cause the error that the original post referred to though
  • Alright I can see that I did that wrong, even in the original Go implementation it is like you wrote. I fixed that. But it's not causing the error I'm having. The error still persists.
  • @SarathSadasivanPillai I've edited the original question. Sorry that I left out that part before.