Маршаллинг времени. Время, чтобы Unix метка времени - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть такая структура

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

, и я хочу иметь метку времени в качестве метки времени Unix вместо того, что по умолчанию делает go (2018-09-21T19:31:03.291Z)

Я пробовалсоздание собственного типа для этого, как это:

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
}

, но я всегда получаю ошибку can not unmarshal timestamp into *main.timestamp при попытке чтения из базы данных.

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

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

Здесь нельзя отменять марку времени.https://github.com/gocql/gocql/blob/799fb0373110eaa4e2e71dd32a9b5903f80dca8f/helpers.go#L30 проблема в том, что он не использует функции Unmarshall.

Редактировать: я ответил на свой вопрос.

Ответы [ 3 ]

0 голосов
/ 23 сентября 2018

Я думаю, что ваш код в порядке - кроме кода в вашем демаршале.Вы не показывает код, где вы Marshalling / Unmarshalling, где фактическая ошибка.

У меня это работает на детской площадке. Golang Playground

Вместо этого (который меняет указатель)

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

Изменение значения

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

Основная функция для использования ваших структур

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)
0 голосов
/ 23 сентября 2018

Хорошо, после того, как многие люди запутались здесь (извините), и я нашел решение.

Маршаллинг для json теперь работает только для того, чтобы исправить совместимость gocql следующим образом:

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

    userlogResult.Messages = append(userlogResult.Messages, message)
}
0 голосов
/ 23 сентября 2018

здесь, когда присваиваете &timestamp{..} для t, это меняет указатель, вместо этого значение, на которое он указывает, должно быть изменено следующим образом

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
}

Пожалуйста, найдите код здесь

Редактировать

Так как при чтении из базы данных вам не удается выполнить демаршаллинг, это не из-за json.unmarshalling, вы должны реализовать sql.Scanner, если выИспользуете sql

Подробности вы найдете здесь => sql.Scanner

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...