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