Сколько байтов в объекте времени Голанга - PullRequest
0 голосов
/ 10 июля 2019

Мне нужно сохранить объект времени в массиве байтов в проекте go, над которым я работаю, и мне нужно заранее объявить размер массива.Я не могу найти длину в байтах, на которые ссылаются нигде.На данный момент я планирую использовать time.MarshalBinary () из библиотеки времени, чтобы преобразовать его в байты и вычислить вручную.Но я хотел знать, есть ли у кого-нибудь ссылка на количество байтов, и если time.MarshalBinary () - лучший метод для преобразования в байты.

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

Ответ на этот вопрос не так прост, как может показаться.Многое зависит от того, сколько деталей вам нужно сохранить при маршалинге.

Как указано в другом ответе, вы можете просто использовать unsafe.Sizeof() для определения размера временного объекта в памяти, но этоимеет небольшое сходство с фактическим маршалированным размером по той простой причине, что он содержит указатель.Если мы посмотрим на определение time.Time, то увидим:

type Time struct {
    // wall and ext encode the wall time seconds, wall time nanoseconds,
    // and optional monotonic clock reading in nanoseconds.
    //
    // From high to low bit position, wall encodes a 1-bit flag (hasMonotonic),
    // a 33-bit seconds field, and a 30-bit wall time nanoseconds field.
    // The nanoseconds field is in the range [0, 999999999].
    // If the hasMonotonic bit is 0, then the 33-bit field must be zero
    // and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext.
    // If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit
    // unsigned wall seconds since Jan 1 year 1885, and ext holds a
    // signed 64-bit monotonic clock reading, nanoseconds since process start.
    wall uint64
    ext  int64

    // loc specifies the Location that should be used to
    // determine the minute, hour, month, day, and year
    // that correspond to this Time.
    // The nil location means UTC.
    // All UTC times are represented with loc==nil, never loc==&utcLoc.
    loc *Location
}

Если вам нужна информация о часовом поясе, хранящаяся в loc, зависит от приложения.Если вы всегда сохраняете время UTC (обычно это лучший подход), то вы можете полностью игнорировать этот бит, что означает, что вы можете получить, сохранив только два uint64 s.

Но даже эти два поля зависят от того,или нет вы используете монотонные часы.При маршалинге данных вы почти наверняка не заботитесь о монотонных часах, независимо от того, закодированы они в этих битах или нет.

Это означает, что в большинстве случаев вы должны иметь возможность хранить объект с полной занятостьюв 64 битах (8 байт), плюс индикатор часового пояса, если необходимо.

Кроме того, в зависимости от необходимой точности вы можете сохранить только поле секунд (отбрасывая точность менее секунды), чтонужно всего 33 бита.Если вам нужны минуты или дни, вы можете использовать еще меньше места.

0 голосов
/ 10 июля 2019

Вы можете использовать usafe.Sizeof , чтобы получить размер в байтах переменной. Я сделал это

package main

import (
    "fmt"
    "time"
    "unsafe"
)

func main() {
    t := time.Now()
    fmt.Printf("a: %T, %d\n", t, unsafe.Sizeof(t))
}

Похоже, его 24 байта! :)

Также MarshalBinary выглядит так, как будто он работает, хотя это зависит от того, куда вы отправляете его и как вы хотите его разархивировать. Может быть проще просто преобразовать его в строку, а затем использовать его, если вы используете его в Javascript или что-то еще.

...