我必须在我正在处理的go项目中将时间对象存储在字节数组中,并且必须预先声明数组的大小。我找不到在任何地方引用的字节长度。在这一点上,我计划使用时间库中的time.MarshalBinary()将其转换为字节并手动确定。但是我想知道是否有人对这是多少个字节的引用以及time.MarshalBinary()是转换为字节的最佳方法。
答案 0 :(得分:3)
这个问题的答案并不像看起来那样简单。在很大程度上取决于您需要在编组中保留多少细节。
正如另一个答案中指出的那样,您可以简单地使用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
。
但是,即使这两个字段也取决于您是否使用单调时钟。封送数据时,几乎可以肯定,您不关心单调时钟,无论它是否已编码在那些位中。
这意味着在大多数情况下,您应该能够以64位(8字节)存储完整的时间对象,并在必要时加上时区指示符。
此外,根据所需的精度,您可能只能存储秒字段(舍弃亚秒精度),仅需要33位。如果您只关心几分钟或几天,则可以使用更少的空间。
答案 1 :(得分:0)
您可以使用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看起来也可以工作,尽管它取决于您将其发送到何处以及如何取消其封送。如果将其转换为字符串,然后在Java语言中使用它,则使用它可能会更容易。