Skip to content

feature: Option to serialize time.Time as wall clock millis/micros/nanos as integers #656

@ssanderson

Description

@ssanderson

Is your feature request related to a problem? Please describe.

This package currently exposes several ways to serialize time.Time values:

type TimeMode int

const (
	// TimeUnix causes time.Time to be encoded as epoch time in integer with second precision.
	TimeUnix TimeMode = iota

	// TimeUnixMicro causes time.Time to be encoded as epoch time in float-point rounded to microsecond precision.
	TimeUnixMicro

	// TimeUnixDynamic causes time.Time to be encoded as integer if time.Time doesn't have fractional seconds,
	// otherwise float-point rounded to microsecond precision.
	TimeUnixDynamic

	// TimeRFC3339 causes time.Time to be encoded as RFC3339 formatted string with second precision.
	TimeRFC3339

	// TimeRFC3339Nano causes time.Time to be encoded as RFC3339 formatted string with nanosecond precision.
	TimeRFC3339Nano

	maxTimeMode
)

All of these options are either lossy w/r/t the time's wall clock time (everything but TimeRFC3339Nano) or dependent on the for-display-only Location component of the time. I believe this means there is no serialization option that guarantees that two times constructed using time.Micro(n) on different machines will serialize identically for all possible values of n, because the current numerical serialization options are lossy, and the RFC3339-based options are location dependent, so two machines with different locations will produce different serializations.

Describe the solution you'd like

I propose adding new options to serialize time.Time as 64-bit integers with milli/micro/nanosecond precision. These would correspond to serializing the time using theTime.UnixMilli, Time.UnixMicro, and time.UnixNano methods. These options would provide location-independent ways of serializing times that give clear precision guarantees, and don't require reasoning about how the range of times you plan to support will interact with rounding behavior of 64-bit floating point. By contrast, the existing floating-point TimeUnixMicro will only be lossless at microsecond precision only up to around 2^53 microseconds. Maybe that works for many applications but it seems hard to reason about.

Describe alternatives you've considered

I'm currently handling this issue in my application by serializing using TimeRFC3339Nano, and then calling .UTC() on any times I want to serialize, which ensures that the location-dependence doesn't cause breakage. This works, but it adds extra boilerplate and needs to be handled correctly at every site where I have a time I want to serialize with cbor. I'd prefer to have a blanket option to say "serialize times as integers with unambiguous millisecond/nanosecond precision".

Additional context
Add any other context or screenshots about the feature request here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions