# Unix Epoch Nanoseconds

Key: `datetime.timestamp.epoch_nanoseconds`

Nanoseconds since Unix epoch (1970-01-01T00:00:00Z). 19-digit integer. OpenTelemetry time\_unix\_nano, Go time.UnixNano(). Distinct from other epoch formats by digit count (19 vs 10/13/16).

Page: <https://meridian.online/docs/projects/finetype/types/datetime/timestamp/epoch_nanoseconds>

Samples: `1705325400000000000`, `1704067199000000000`, `1717228530000000000`

## Background

### Origin

The Unix time 0 is exactly midnight UTC on 1 January 1970.[[1]](https://en.wikipedia.org/wiki/Unix_time) In Unix time, every day contains exactly 86400 seconds.[[1]](https://en.wikipedia.org/wiki/Unix_time) Unix time values are sometimes stored with higher granularity, such as microseconds or nanoseconds.[[1]](https://en.wikipedia.org/wiki/Unix_time) Go's time package documents UnixNano as returning a time as the number of nanoseconds elapsed since January 1, 1970 UTC.[[2]](https://pkg.go.dev/time) Go's documentation says the result of UnixNano is undefined for a date before the year 1678 or after 2262, because the value cannot be represented by an int64.[[2]](https://pkg.go.dev/time)

FineType's label definition gives the type the alias unix\_nano.[[3]](https://github.com/meridian-online/finetype/blob/main/labels/definitions_datetime.yaml)

### Use

OpenTelemetry's Metrics Data Model records the time a value was sampled in a field called time\_unix\_nano.[[4]](https://opentelemetry.io/docs/specs/otel/metrics/data-model/) The OpenTelemetry Metrics Data Model specifies histogram time values as nanoseconds since the UNIX Epoch (00:00:00 UTC on 1 January 1970).[[4]](https://opentelemetry.io/docs/specs/otel/metrics/data-model/) OpenTelemetry's log record protocol stores time\_unix\_nano as a fixed64 field holding UNIX Epoch time in nanoseconds since 00:00:00 UTC on 1 January 1970.[[5]](https://raw.githubusercontent.com/open-telemetry/opentelemetry-proto/main/opentelemetry/proto/logs/v1/logs.proto) In OpenTelemetry's log record protocol, a time\_unix\_nano value of 0 indicates an unknown or missing timestamp.[[5]](https://raw.githubusercontent.com/open-telemetry/opentelemetry-proto/main/opentelemetry/proto/logs/v1/logs.proto) OpenTelemetry's trace protocol gives a span's start\_time\_unix\_nano and end\_time\_unix\_nano as UNIX Epoch time in nanoseconds.[[6]](https://raw.githubusercontent.com/open-telemetry/opentelemetry-proto/main/opentelemetry/proto/trace/v1/trace.proto) InfluxDB's line protocol takes a Unix timestamp whose default precision is nanoseconds.[[7]](https://docs.influxdata.com/influxdb/v2/reference/syntax/line-protocol/) Wikipedia's article on Unix time says APFS and ext4 both use Unix time in nanoseconds for file timestamps.[[1]](https://en.wikipedia.org/wiki/Unix_time)

Treat a zero in an OpenTelemetry export as a missing value rather than as midnight on 1 January 1970. (Meridian's view) Keep these values as 64-bit integers or as text until they are converted, rather than as floating-point numbers. (Meridian's view)

DuckDB's make\_timestamp\_ns function converts nanoseconds since the epoch to a timestamp.[[8]](https://duckdb.org/docs/current/sql/functions/timestamp.html) DuckDB's documentation gives make\_timestamp\_ns(1667810584123456789) as returning 2022-11-07 08:43:04.123456789.[[8]](https://duckdb.org/docs/current/sql/functions/timestamp.html) DuckDB's single-argument make\_timestamp function expects microseconds since the epoch, not nanoseconds.[[8]](https://duckdb.org/docs/current/sql/functions/timestamp.html) pandas converts integer epoch times with to\_datetime, and its default unit is nanoseconds.[[9]](https://pandas.pydata.org/docs/user_guide/timeseries.html) The pandas documentation says a 64-bit integer at nanosecond resolution can span only approximately 584 years.[[9]](https://pandas.pydata.org/docs/user_guide/timeseries.html) The pandas documentation gives Timestamp.max at nanosecond resolution as 2262-04-11 23:47:16.854775807.[[9]](https://pandas.pydata.org/docs/user_guide/timeseries.html)

Before parsing, check that the column's digit count and the dates it decodes to fit what you expect, so that a column in another unit is not decoded as nanoseconds. (Meridian's view) Decoding a few values by hand and comparing them with a known event in the data is the quickest way to confirm the unit. (Meridian's view)

## Sources

1. [Unix time](https://en.wikipedia.org/wiki/Unix_time) — secondary source
2. [time package - time - Go Packages](https://pkg.go.dev/time) — documentation
3. [finetype/labels/definitions\_datetime.yaml](https://github.com/meridian-online/finetype/blob/main/labels/definitions_datetime.yaml) — FineType
4. [Metrics Data Model](https://opentelemetry.io/docs/specs/otel/metrics/data-model/) — documentation
5. [logs.proto](https://raw.githubusercontent.com/open-telemetry/opentelemetry-proto/main/opentelemetry/proto/logs/v1/logs.proto) — documentation
6. [trace.proto](https://raw.githubusercontent.com/open-telemetry/opentelemetry-proto/main/opentelemetry/proto/trace/v1/trace.proto) — documentation
7. [Line protocol \| InfluxDB OSS v2 Documentation](https://docs.influxdata.com/influxdb/v2/reference/syntax/line-protocol/) — documentation
8. [Timestamp Functions](https://duckdb.org/docs/current/sql/functions/timestamp.html) — documentation
9. [Time series / date functionality](https://pandas.pydata.org/docs/user_guide/timeseries.html) — documentation
