Timestamps
Learn how to work effectively with timestamps in the Synnax TypeScript client.
Working with high-resolution timestamps in JavaScript is tricky. We provide several utility classes to make it easier.
JavaScript’s Limitations
Synnax stores timestamps as 64-bit integers representing the number of
nanoseconds elapsed since the unix epoch in UTC. This is unlike JavaScript’s
native Date
object, which only supports millisecond precision.
Numbers in JavaScript are represented as 64-bit floating point numbers, which means that they can only represent integers up to 2^53 accurately. This means that you may lose precision for certain timestamps. Also, doing arithmetic with timestamps expressed as floating point numbers can lead to rounding errors.
TimeStamp
Synnax provides the TimeStamp
utility class to effectively work with
nanosecond timestamps in JavaScript. It wraps a bigint
to store a unix
timestamp in nanoseconds.
Constructing a TimeStamp
There are several easy ways to construct a TimeStamp
:
import { TimeStamp } from "@synnaxlabs/client";
// From the current time
const now = TimeStamp.now();
// From a Date object
const ts = new TimeStamp(new Date("2021-01-01T00:00:00Z"));
// From a string
const ts = new TimeStamp("2021-01-01T00:00:00Z");
// From a number of nanoseconds
const ts = new TimeStamp(1000000000);
// From a bigint of nanoseconds
const ts = new TimeStamp(BigInt(1000000000));
// From utility functions
const ts = TimeStamp.now().sub(TimeStamp.seconds(1));
Any of these formats can be passed to common methods used throughout the Synnax
client. The union of these formats is called a CrudeTimeStamp
. Examples
include read
, write
, openIterator
, openStreamer
, and openWriter
.
Converting to a Date
You can convert a TimeStamp
to a Date
object using the date
method:
const ts = TimeStamp.now();
const date = ts.date();
Arithmetic
You can perform arithmetic on TimeStamp
objects:
const ts1 = TimeStamp.now();
const ts2 = ts1.add(TimeStamp.seconds(1));
const diff = ts2.sub(ts1);
Comparisons
You can compare TimeStamp
objects:
const ts1 = TimeStamp.now();
const ts2 = ts1.add(TimeStamp.seconds(1));
const isAfter = ts2.after(ts1);
const isAfterEq = ts2.afterEq(ts1);
const isBefore = ts1.before(ts2);
const isBeforeEq = ts1.beforeEq(ts2);
Accessing the Underlying Value
You can access the underlying bigint
value using the value
property:
const ts = TimeStamp.now();
const value = ts.value;
TimeSpan
TimeSpan
is a utility class that represents a duration of time. It wraps a
bigint
to store a duration in nanoseconds.
Constructing a TimeSpan
You can construct a TimeSpan
directly from a number of nanoseconds, but it’s generally
easier to use the utility functions:
import { TimeSpan } from "@synnaxlabs/client";
// From a number of nanoseconds
const span = new TimeSpan(1000000000);
// From a utility function
const span = TimeSpan.hours(1);
// From multiple utility functions
const span = TimeSpan.days(1).add(TimeSpan.hours(1)).add(TimeSpan.minutes(1));
Performing Arithmetic
You can perform arithmetic on TimeSpan
objects:
const span1 = TimeSpan.hours(1);
const span2 = span1.add(TimeSpan.minutes(1));
const diff = span2.sub(span1);
Accessing the Underlying Value
You can access the underlying bigint
value using the value
property:
const span = TimeSpan.hours(1);
const value = span.value;
TimeRange
TimeRange
is another utility class that represents a range of time. It
consists of two TimeStamp
objects called start
and end
.
Constructing a TimeRange
You can construct a TimeRange
from two timestamps in any of the formats that
TimeStamp
supports:
import { TimeRange } from "@synnaxlabs/client";
const start = TimeStamp.now();
const end = start.add(TimeStamp.seconds(1));
// From TimeStamp objects
const range = new TimeRange(start, end);
// From dates
const range = new TimeRange(
new Date("2021-01-01T00:00:00Z"),
new Date("2021-01-01T00:00:01Z")
);
// From strings
const range = new TimeRange("2021-01-01T00:00:00Z", "2021-01-01T00:00:01Z");
// From numbers
const range = new TimeRange(1000000000, 2000000000);
// From bigints
const range = new TimeRange(BigInt(1000000000), BigInt(2000000000));
// From a mix of formats
const range = new TimeRange(BigInt(1000000000), "2021-01-01T00:00:01Z");
// From an object
const range = TimeRange.from({
start: TimeStamp.now(),
end: TimeStamp.now().add(TimeStamp.seconds(1))
});
Checking if a TimeStamp Is in a TimeRange
You can check if a TimeStamp
is in a TimeRange
using the contains
method:
const range = new TimeRange(
new Date("2021-01-01T00:00:00Z"),
new Date("2021-01-01T00:00:01Z")
);
const ts = new TimeStamp("2021-01-01T00:00:00.5Z");
const isIn = range.contains(ts);
console.log(isIn); // true
Checking if Two TimeRanges Overlap
You can check if two TimeRange
objects overlap using the overlaps
method:
const range1 = new TimeRange(
new Date("2021-01-01T00:00:00Z"),
new Date("2021-01-01T00:00:01Z")
);
const range2 = new TimeRange(
new Date("2021-01-01T00:00:00.5Z"),
new Date("2021-01-01T00:00:01.5Z")
);
const doesOverlap = range1.overlapsWith(range2);
console.log(doesOverlap); // true
Getting the TimeSpan of a TimeRange
You can get the TimeSpan
of a TimeRange
using the span
property:
const range = new TimeRange(
new Date("2021-01-01T00:00:00Z"),
new Date("2021-01-01T00:00:01Z")
);
const span = range.span;
console.log(span.seconds); // 1