High-precision date/time in C

I've created a C library called vaqt that offers data types and functions for handling time and duration, with nanosecond precision. Works with C99 (C11 is recommended on Windows for higher precision).

Concepts

vaqt is a partial port of Go's time package. It works with two types of values: Time and Duration.

Time is a pair (seconds, nanoseconds), where seconds is the 64-bit number of seconds since zero time (0001-01-01 00:00:00 UTC) and nanoseconds is the number of nanoseconds within the current second (0-999999999). Time can represent dates billions of years in the past or future with nanosecond precision.

  since     within
  0-time    second
┌─────────┬─────────────┐
│ seconds │ nanoseconds │
└─────────┴─────────────┘
  64 bit    32 bit

Time is always operated in UTC, but you can convert it from/to a specific timezone.

Duration is a 64-bit number of nanoseconds. It can represent values up to about 290 years.

┌─────────────┐
│ nanoseconds │
└─────────────┘
  64 bit

Features

vaqt provides functions for common date and time operations.

Creating time values:

time_now()
time_date(year, month, day, hour, min, sec, nsec, offset_sec)

Extracting time fields:

time_get_year(t)
time_get_month(t)
time_get_day(t)
time_get_clock(t)
time_get_hour(t)
time_get_minute(t)
time_get_second(t)
time_get_nano(t)
time_get_weekday(t)
time_get_yearday(t)
time_get_isoweek(t)

Unix time:

time_unix(sec, nsec)
time_unix_milli(msec)
time_unix_micro(usec)
time_unix_nano(nsec)
time_to_unix(t)
time_to_unix_milli(t)
time_to_unix_micro(t)
time_to_unix_nano(t)

Calendar time:

time_tm(tm, offset_sec)
time_to_tm(t, offset_sec)

Time comparison:

time_after(t, u)
time_before(t, u)
time_compare(t, u)
time_equal(t, u)
time_is_zero(t)

Time arithmetic:

time_add(t, d)
time_add_date(t, years, months, days)
time_sub(t, u)
time_since(t)
time_until(t)

Rounding:

time_truncate(t, d)
time_round(t, d)

Formatting:

time_fmt_iso(t, offset_sec)
time_fmt_datetime(t, offset_sec)
time_fmt_date(t, offset_sec)
time_fmt_time(t, offset_sec)
time_parse(s)

Marshaling:

time_unmarshal_binary(b);
time_marshal_binary(t)

Check the API reference for more details.

Usage example

Here's a basic example of how to use vaqt to work with time:

// Get current time.
Time t = time_now();

// Create time manually.
Time td = time_date(2011, TIME_NOVEMBER, 18, 15, 56, 35, 666777888, 0);

// Create time from Unix time.
Time tu = time_unix(1321631795, 666777888);

// Parse time from string.
Time tp = time_parse("2011-11-18T15:56:35.666777888Z");

// Get time parts.
int iso_year, iso_week;
time_get_isoweek(t, &iso_year, &iso_week);
int yearday = time_get_yearday(t);
enum Weekday weekday = time_get_weekday(t);

// Add duration to a time.
Time ta = time_add(t, 30 * TIME_SECOND);

// Subtract two times.
Time t1 = time_date(2024, TIME_AUGUST, 6, 21, 22, 45, 0, 0);
Time t2 = time_date(2024, TIME_AUGUST, 6, 21, 22, 15, 0, 0);
Duration d = time_sub(t1, t2);

// Convert time to string.
char buf[64];
size_t n = time_fmt_iso(t, 0, buf, sizeof(buf));
// buf = "2011-11-18T15:56:35.666777888Z"

Final thoughts

If you work with date and time in C, you might find vaqt useful.

See the nalgeon/vaqt repo for all the details.

★ Subscribe to keep up with new posts.