Skip to content

time #

Description

V's time module, provides utilities for working with time and dates:

  • parsing of time values expressed in one of the commonly used standard time/date formats
  • formatting of time values
  • arithmetic over times/durations
  • converting between local time and UTC (timezone support)
  • stop watches for accurately measuring time durations
  • sleeping for a period of time

Dates before year 1 use the proleptic Gregorian calendar with astronomical year numbering: year 0 is 1 BC and is a leap year. Unix timestamp and day-offset conversions preserve dates at the 400-year cycle boundaries before year 0, including March 1 and 2 of years -400, -800 and -1200. days_from_unix_epoch, day_of_week and Time.week_of_year() use the same calendar for year zero and negative years. Weekdays remain 1 (Monday) through 7 (Sunday), and ISO week numbers repeat every 400 years. The zero Time value has Unix timestamp -62167219200.

time.ticks() returns milliseconds since the UNIX epoch on Unix platforms. On Windows it returns a 64-bit count of milliseconds since system startup, which does not wrap after 49.7 days. The Windows counter is resolved at runtime so it also works with bundled TCC versions whose import library does not list GetTickCount64.

Examples

You can see the current time. See:

import time

println(time.now())

time.Time values can be compared, see:

import time

const time_to_test = time.Time{
    year:       1980
    month:      7
    day:        11
    hour:       21
    minute:     23
    second:     42
    nanosecond: 123456789
}

println(time_to_test.format())

assert '1980-07-11 21:23' == time_to_test.format()
assert '1980-07-11 21:23:42' == time_to_test.format_ss()
assert '1980-07-11 21:23:42.123' == time_to_test.format_ss_milli()
assert '1980-07-11 21:23:42.123456' == time_to_test.format_ss_micro()
assert '1980-07-11 21:23:42.123456789' == time_to_test.format_ss_nano()

You can also parse strings to produce time.Time values, see:

import time

s := '2018-01-27 12:48:34'
t := time.parse(s) or { panic('failing format: ${s} | err: ${err}') }
println(t)
println(t.unix())

V's time module also has these parse methods:

Month and weekday names in parse_format may end the input. For example, time.parse_format('May', 'MMMM')! and time.parse_format('Jul', 'MMM')! return times in May and July, respectively; weekday tokens also accept a terminal name.

parse_format(s, format) requires the format to cover the entire input, including literals. Unmatched trailing text or whitespace returns an error instead of parsing only a prefix.

Unpadded clock tokens H, h, k, m, and s accept one or two digits, including leading zeros. Their doubled forms require exactly two digits. Thus layouts such as YYYY-MM-DD k:m:s read back both 2024-07-15 3:4:5 and 2024-07-15 23:40:50.

parse_format defaults an omitted month to January. Day-only layouts such as time.parse_format('31', 'DD')! therefore accept January 31; an explicit month still enforces its actual length.

Time.custom_format('YYYY') pads nonnegative years to at least four digits, so year 100 is written as 0100. For nonnegative years, YY writes the final two year digits with leading zeros. Negative years retain their existing YYYY and YY representations.

parse_format supports A for AM/PM and a for am/pm. Use these markers with an hour from 1 to 12, for example time.parse_format('02:30:45PM', 'hh:mm:ssA')! returns hour 14, while 12:00:00AM returns hour 0. Layouts without a marker retain their existing 24-hour behavior.

fn parse(s string) !Time
fn parse_iso8601(s string) !Time
fn parse_rfc2822(s string) !Time
fn parse_rfc3339(s string) !Time

time.new(...) validates the provided fields before calculating the Unix timestamp. Omitted month and day values default to 1, and out-of-range values panic. Use t.is_zero() to check whether a time.Time is still its zero value before formatting or serializing it.

IANA time zone data can be loaded by name and used to convert Unix timestamps or UTC Time values to that location's calendar time. load_location searches ZONEINFO, system zoneinfo paths, and V's installed zoneinfo.zip. Programs that need embedded time zone data (no system zoneinfo, portable binaries) can import time.tzdata.

load_location('Local') uses the system time zone when TZ is unset. On POSIX, setting TZ to an empty string selects UTC. On Windows, os.setenv('TZ', '', true) removes TZ, so the local location uses the system time zone. To select UTC explicitly on either platform, use load_location('UTC') or set TZ to the POSIX rule UTC0.

import time
import time.tzdata as _

shanghai := time.load_location('Asia/Shanghai')!
local := time.unix(1_704_067_200).in(shanghai)!
assert local.format_ss() == '2024-01-01 08:00:00'
assert local.unix() == 1_704_067_200
assert (local.zone()!).offset == 28_800

IANA-zoned values keep unix as the absolute UTC epoch instant. Calendar fields (year, hour, ...) are wall time in that location. Prefer t.location() / t.zone() over the older is_local flag: is_local only marks system-local wall time with a fixed process offset and is left false on IANA-zoned Time values.

parse_rfc3339 and parse_iso8601 keep a non-zero numeric UTC offset in the same way: the calendar fields stay as written, and t.zone() returns a fixed zone with that offset (in seconds east of UTC). Inputs ending in Z, +00:00 or -00:00 give plain UTC values without a location.

import time

t := time.parse_rfc3339('2024-07-15T18:30:45-05:00')!
assert t.format_ss() == '2024-07-15 18:30:45'
assert (t.zone()!).offset == -18_000
assert t.format_rfc3339() == '2024-07-15T23:30:45.000Z'

The bundled vlib/time/tzdata/zoneinfo.zip is a store-only (uncompressed) zip of IANA zoneinfo files for offline use via import time.tzdata. Refresh it from a full IANA tzdb source archive with packrat data enabled, so named zones retain their pre-1970 histories. For example, from an extracted tzdb source archive:

make PACKRATDATA=backzone PACKRATLIST= ZFLAGS='-b slim' \
  DESTDIR=/tmp/tzdb-full TZDIR=/zoneinfo posix_only
cd /tmp/tzdb-full/zoneinfo
find . -type f -print | LC_ALL=C sort | sed 's#^./##' | \
  zip -0 -X /path/to/v/vlib/time/tzdata/zoneinfo.zip -@

time.parse_duration(s) parses a string such as 1h30m, -1.5s or 300ms into a time.Duration. The format is the one of Go's time.ParseDuration: an optional sign, followed by one or more decimal numbers, each with an optional fraction and a unit. The units are ns, us (or µs), ms, s, m and h; only 0 can be written without one. A string that is not a duration, a number without a unit, an unknown unit such as d, and a duration that does not fit in the i64 range of nanoseconds are reported as errors:

import time

timeout := time.parse_duration('1h30m')!
assert timeout == 90 * time.minute
assert time.parse_duration('-1.5s')! == -1500 * time.millisecond
assert time.parse_duration('2h45m30.5s')!.seconds() == 9930.5

time.parse_duration('5') or { assert err.msg() == 'missing unit in duration: "5"' }
time.parse_duration('1d') or { assert err.msg() == 'unknown unit "d" in duration: "1d"' }

Duration.str() is meant for display. For a minute or more it writes forms such as 1:30:00, which are not duration strings, so parse_duration does not read them back. Negative durations retain a single minus sign even at the minimum i64 value: time.Duration(i64(-9223372036854775807) - 1).str() returns -2562047:47:16. It renders the maximum i64 duration as 2562047:47:16, including time.infinite. The time.infinite constant still tells APIs that support it to wait forever; displaying it uses the same duration format as other finite i64 values.

Another very useful feature of the time module is the stop watch, for when you want to measure short time periods, elapsed while you executed other tasks. See:

import time

fn do_something() {
    time.sleep(510 * time.millisecond)
}

fn main() {
    sw := time.new_stopwatch()
    do_something()
    println('Note: do_something() took: ${sw.elapsed().milliseconds()} ms')
}

A wait that needs to participate in a select uses sync.new_timer, which sends the time on a channel: see the sync module.

Time.from_json_string accepts a quoted value returned by to_json() as well as the unquoted value passed by json2. Unix timestamp strings contain decimal digits with an optional leading minus and must fit in i64. Empty, malformed, and overflowing values return an error. clean12() uses a single-digit hour when appropriate, followed by a.m. or p.m..

unix_milli, unix_micro and unix_nano round the seconds component down for negative timestamps, keeping Time.nanosecond in 0 .. 999_999_999. unix_nanosecond and unix_microsecond carry out-of-range subsecond arguments into the seconds component. Location.unix_nanosecond_to_local applies the same normalization before choosing the zone.

Calendar arithmetic and monotonic readings

Time.weekday() returns a Weekday enum using ISO numbering: Monday is 1 and Sunday is 7. Time.add_date(years, months, days) normalizes the requested month, clamps the original day to that month's last day, then applies the day offset. January 31 plus one month becomes February 28 or 29. The method preserves nanoseconds and the associated location.

Ambiguous times prefer the original UTC offset when it remains valid. Nonexistent times use the original offset and normalize to a nearby valid time: in New York, advancing March 9, 2024 at 02:30 by one day gives March 10 at 03:30; moving back from March 11 at 02:30 gives March 10 at 01:30. A zero date adjustment preserves the original instant.

time.clock() returns monotonic milliseconds with a platform-dependent origin. Subtract two readings to measure elapsed time; the value is not a Unix timestamp or a portable process age.

Darwin clock initialization retains its native function declarations in cached and uncached C builds, preserving headerless output without adding a Mach SDK include to the module.

Constants #

@[markused]
const nanosecond = Duration(1)
const microsecond = Duration(1000 * nanosecond)
const millisecond = Duration(1000 * microsecond)
const second = Duration(1000 * millisecond)
const minute = Duration(60 * second)
const hour = Duration(60 * minute)
const infinite = Duration(i64(9223372036854775807))

day = Duration(24 * hour) infinite is the maximum i64 duration, used by APIs that support waiting forever.

const http_date_len = 29

http_date_len is the byte length of an HTTP-date value (RFC 9110 IMF-fixdate), e.g. "Sun, 06 Nov 1994 08:49:37 GMT".

const days_string = 'MonTueWedThuFriSatSun'
const long_days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']!
const month_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]!
const months_string = 'JanFebMarAprMayJunJulAugSepOctNovDec'
const long_months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
	'September', 'October', 'November', 'December']
const absolute_zero_year = i64(-292277022399)

The unsigned zero year for internal calculations. Must be 1 mod 400, and times before it will not compute correctly, but otherwise can be changed at will.

const seconds_per_minute = 60
const seconds_per_hour = 60 * seconds_per_minute
const seconds_per_day = 24 * seconds_per_hour
const seconds_per_week = 7 * seconds_per_day
const days_per_400_years = days_in_year * 400 + 97
const days_per_100_years = days_in_year * 100 + 24
const days_per_4_years = days_in_year * 4 + 1
const days_in_year = 365
const days_before = [
	0,
	31,
	31 + 28,
	31 + 28 + 31,
	31 + 28 + 31 + 30,
	31 + 28 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
]!

fn clock #

fn clock() i64

clock returns a monotonic clock reading in milliseconds. Its origin is platform-dependent; subtract readings to measure elapsed time.

fn date_from_days_after_unix_epoch #

fn date_from_days_after_unix_epoch(days int) Time

date_from_days_after_unix_epoch - convert number of days after the unix epoch 1970-01-01, to a Time. Only the year, month and day of the returned Time will be set, everything else will be 0.

fn day_of_week #

fn day_of_week(y int, m int, d int) int

day_of_week returns the current day of a given year, month, and day, as an integer. The result is from 1 (Monday) to 7 (Sunday), also for the years before 1 of the proleptic Gregorian calendar, where the year 0 is 1 BC.

fn days_from_unix_epoch #

fn days_from_unix_epoch(year int, month int, day int) int

days_from_unix_epoch - return the number of days since the Unix epoch 1970-01-01. A detailed description of the algorithm here is in: http://howardhinnant.github.io/date_algorithms.html Note that function will return negative values for days before 1970-01-01.

fn days_in_month #

fn days_in_month(month int, year int) !int

days_in_month returns a number of days in a given month.

fn is_leap_year #

fn is_leap_year(year int) bool

is_leap_year checks if a given a year is a leap year.

fn load_location #

fn load_location(name string) !&Location

load_location loads an IANA time zone location from ZONEINFO, system zoneinfo paths, V's installed zoneinfo.zip, or registered fallback loaders.

fn new #

fn new(t Time) Time

new returns a time struct with the calculated Unix time.

fn new_stopwatch #

fn new_stopwatch(opts StopWatchOptions) StopWatch

new_stopwatch initializes a new StopWatch with the current time as start.

fn now #

fn now() Time

now returns the current local time.

fn offset #

fn offset() int

offset returns time zone UTC offset in seconds.

fn parse #

fn parse(s string) !Time

parse returns the time from a date string in "YYYY-MM-DD HH:mm:ss" format.

fn parse_duration #

fn parse_duration(s string) !Duration

parse_duration parses a duration string, such as '300ms', '-1.5h' or '2h45m30.5s'. A duration string is an optional sign followed by one or more decimal numbers, each with an optional fraction and a mandatory unit suffix. The valid units are ns, us (or µs), ms, s, m and h. A zero duration can also be written without a unit, as 0, +0 or -0. It returns an error when s is not a valid duration string, or when the duration does not fit in the i64 range of nanoseconds that a Duration can hold.

Examples

assert time.parse_duration('1h30m')! == 90 * time.minute
assert time.parse_duration('-1.5s')! == -1500 * time.millisecond
assert time.parse_duration('1.000000001s')!.nanoseconds() == 1_000_000_001

fn parse_format #

fn parse_format(s string, format string) !Time

parse_format parses the string s, as a custom format, containing the following specifiers: The format must cover the entire input; trailing text, including whitespace, is rejected.

Category Format Description
Year YYYY 4 digit year, 0000..9999
YY 2 digit year, 00..99
Month M month, 1..12
MM month, 2 digits, 01..12
MMM month, three letters, Jan..Dec
MMMM name of month
Day D day of the month, 1..31
DD day of the month, 01..31
d day of week, 0..6
c day of week, 1..7
dd day of week, Su..Sa
ddd day of week, Sun..Sat
dddd day of week, Sunday..Saturday
Hour H hour, 0..23
HH hour, 00..23
h hour, 0..23
hh hour, 0..23
k hour, 0..23
kk hour, 0..23
Minute m minute, 0..59
mm minute, 0..59
Second s second, 0..59
ss second, 0..59
AM/PM A AM or PM; hour must be 1..12
a am or pm; hour must be 1..12
Unpadded clock tokens H, h, k, m and s accept one or two digits; their doubled forms require exactly two digits. Leading zeros are accepted for clock tokens.

fn parse_http_header_string #

fn parse_http_header_string(s string) !Time

Convert header string formatted as RFC 2616 to Time.

fn parse_iso8601 #

fn parse_iso8601(s string) !Time

parse_iso8601 parses the ISO 8601 time format yyyy-MM-ddTHH:mm:ss.dddddd+dd:dd as local time. The fraction part is difference in milli seconds, and the last part is offset from UTC time. Both can be +/- HH:mm . A Z, +00:00 or -00:00 suffix returns a UTC time. Any other offset is kept, as in parse_rfc3339: the calendar fields stay as written, zone() reports the offset, and unix() is the absolute instant. See https://en.wikipedia.org/wiki/ISO_8601 . Remarks: not all of ISO 8601 is supported; checks and support for leapseconds should be added.

fn parse_rfc2616 #

fn parse_rfc2616(s string) !Time

parse_rfc2616 returns the time from a date string in RFC 3339 datetime format. Wed, 06 Nov 2024 08:49:37 GMT ; RFC 822, updated by RFC 1123 Wednesday, 06-Nov-24 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 Wed Nov 6 08:49:37 2024 ; ANSI C's asctime() format

fn parse_rfc2822 #

fn parse_rfc2822(s string) !Time

parse_rfc2822 returns the time from a date string in RFC 2822 datetime format.

fn parse_rfc3339 #

fn parse_rfc3339(s string) !Time

parse_rfc3339 returns the time from a date string in RFC 3339 datetime format. A Z, +00:00 or -00:00 suffix returns a UTC time. Any other numeric offset is kept: the result has the calendar fields as written, in a fixed-offset location whose zone() reports that offset, while unix() and the format_rfc3339*() methods give the same absolute (UTC) instant. For example, 2024-07-15T18:30:45-05:00 gives hour 18, zone()!.offset == -18000, and format_rfc3339() returns 2024-07-15T23:30:45.000Z. See also https://ijmacd.github.io/rfc3339-iso8601/ for a visual reference of the differences between ISO-8601 and RFC 3339.

fn portable_timegm #

fn portable_timegm(t &C.tm) i64

portable_timegm does the same as C._mkgmtime, but unlike it, can work with dates before the Unix epoch of 1970-01-01 .

fn register_zoneinfo_loader #

fn register_zoneinfo_loader(loader ZoneinfoLoaderFn)

register_zoneinfo_loader registers a fallback loader for IANA time zone data. Registered loaders are used after ZONEINFO, system zoneinfo paths, and V's installed zoneinfo.zip have been tried.

fn since #

fn since(t Time) Duration

since returns the time duration elapsed since a given time.

fn sleep #

fn sleep(duration Duration)

sleep suspends the execution of the calling thread for a given duration (in nanoseconds).

fn sys_mono_now #

fn sys_mono_now() u64

sys_mono_now returns a monotonically increasing time, NOT a time adjusted for daylight savings, location etc.

fn ticks #

fn ticks() i64

ticks returns the number of milliseconds since the UNIX epoch. On Windows ticks returns the number of milliseconds elapsed since system start. Its 64-bit uptime counter does not wrap after 49.7 days.

fn unix #

fn unix(epoch i64) Time

unix returns a Time calculated from the given Unix timestamp in seconds since 1970-01-01 .

fn unix_micro #

fn unix_micro(us i64) Time

unix_micro returns a Time calculated from the given Unix timestamp in microseconds since 1970-01-01 .

fn unix_microsecond #

fn unix_microsecond(epoch i64, microsecond int) Time

unix_microsecond returns a Time struct, given an Unix timestamp in seconds, and a microsecond value. A microsecond outside 0 .. 999_999 is carried into the seconds, as in unix_nanosecond.

fn unix_milli #

fn unix_milli(ms i64) Time

unix_milli returns a Time calculated from the given Unix timestamp in milliseconds since 1970-01-01 .

fn unix_nano #

fn unix_nano(ns i64) Time

unix_nano returns a Time calculated from the given Unix timestamp in nanoseconds since 1970-01-01 .

fn unix_nanosecond #

fn unix_nanosecond(abs_unix_timestamp i64, nanosecond int) Time

unix_nanosecond returns a Time struct given a Unix timestamp in seconds and a nanosecond value. A nanosecond outside 0 .. 999_999_999 is carried into the seconds, so the result is the same instant with its nanosecond field in that range: unix_nanosecond(0, -1) is 1969-12-31 23:59:59.999999999 .

fn unix_now #

fn unix_now() i64

unix_now returns the current UNIX time in seconds (UTC), i.e. the value that utc().unix() would produce, without constructing a Time (no calendar conversion, no allocation). It is the cheapest wall-clock read available — a plain time() call, served from the vDSO on Linux — and is the natural choice for second-resolution caches, timeouts and TTL checks.

fn update_http_header #

@[unsafe]
fn update_http_header(dst &u8, dst_len int, last_unix i64, now_unix i64) !

update_http_header refreshes an HTTP-date previously written at dst (by write_http_header) from last_unix to now_unix, rewriting ONLY the digits whose value changed: within the same minute that is the 2 seconds digits; minute and hour rollovers add 2 digits each; a day rollover (or last_unix <= 0 / now_unix <= 0) falls back to a full write_http_header, which is the only path that pays calendar math — at a 1 Hz refresh cadence, once per day. The caller passes the same UTC unix seconds it will keep for the next call. No allocation on the success path.

fn utc #

fn utc() Time

utc returns the current UTC time.

fn FormatDate.from #

fn FormatDate.from[W](input W) !FormatDate

from returns the FormatDate value of an integer or of a field name, or an error if there is none.

fn FormatDelimiter.from #

fn FormatDelimiter.from[W](input W) !FormatDelimiter

from returns the FormatDelimiter value of an integer or of a field name, or an error if there is none.

fn FormatTime.from #

fn FormatTime.from[W](input W) !FormatTime

from returns the FormatTime value of an integer or of a field name, or an error if there is none.

fn Time.new #

fn Time.new(t Time) Time

Time.new returns a time struct with the calculated Unix time.

fn Weekday.from #

fn Weekday.from[W](input W) !Weekday

from returns the Weekday value of an integer or of a field name, or an error if there is none.

type Duration #

type Duration = i64

A lot of these are taken from the Go library.

fn (Duration) nanoseconds #

fn (d Duration) nanoseconds() i64

nanoseconds returns the duration as an integer number of nanoseconds.

fn (Duration) microseconds #

fn (d Duration) microseconds() i64

microseconds returns the duration as an integer number of microseconds.

fn (Duration) milliseconds #

fn (d Duration) milliseconds() i64

milliseconds returns the duration as an integer number of milliseconds.

fn (Duration) seconds #

fn (d Duration) seconds() f64

The following functions return floating point numbers because it's common to consider all of them in sub-one intervals seconds returns the duration as a floating point number of seconds.

fn (Duration) minutes #

fn (d Duration) minutes() f64

minutes returns the duration as a floating point number of minutes.

fn (Duration) hours #

fn (d Duration) hours() f64

hours returns the duration as a floating point number of hours.

fn (Duration) days #

fn (d Duration) days() f64

days returns the duration as a floating point number of days.

fn (Duration) str #

fn (d Duration) str() string

str pretty prints the duration over the full i64 range, including infinite.

h:m:s      // 5:02:33
m:s.mi<s>  // 2:33.015
s.mi<s>    // 33.015s
mi.mc<ms>  // 15.007ms
mc.ns<ns>  // 7.234us
ns<ns>     // 234ns

fn (Duration) debug #

fn (d Duration) debug() string

debug returns a detailed breakdown of the Duration, as: 'Duration: - 50days, 4h, 3m, 7s, 541ms, 78us, 9ns'.

fn (Duration) times #

fn (d Duration) times(x f64) Duration

times allows you to return fractional unit durations, based on an existing duration. For example, you can: half_an_hour := time.hour.times(0.5) .

fn (Duration) sys_milliseconds #

fn (d Duration) sys_milliseconds() int

some *nix system functions (e.g. C.poll(), C.epoll_wait()) accept an int value as timeout in milliseconds with the special value -1 meaning "infinite"

fn (Duration) timespec #

Available on Unix only.

fn (d Duration) timespec() C.timespec

return absolute timespec for now()+d

type ZoneinfoLoaderFn #

type ZoneinfoLoaderFn = fn (name string) ![]u8

enum FormatDate #

enum FormatDate {
	ddmmyy
	ddmmyyyy
	mmddyy
	mmddyyyy
	mmmd
	mmmdd
	mmmddyy
	mmmddyyyy
	no_date
	yyyymmdd
	yymmdd
}

FormatDelimiter contains different date formats.

enum FormatDelimiter #

enum FormatDelimiter {
	dot
	hyphen
	slash
	space
	no_delimiter
}

FormatDelimiter contains different time/date delimiters.

enum FormatTime #

enum FormatTime {
	hhmm12
	hhmm24
	hhmmss12
	hhmmss24
	hhmmss24_milli
	hhmmss24_micro
	hhmmss24_nano
	no_time
}

FormatDelimiter contains different time formats.

enum Weekday #

enum Weekday {
	monday = 1
	tuesday
	wednesday
	thursday
	friday
	saturday
	sunday = 7
}

Weekday is the day of the week in ISO 8601 numbering (Monday = 1 … Sunday = 7), matching the builtin day_of_week and Time.day_of_week.

struct C._FILETIME #

Available on Windows only.

struct C._FILETIME {
pub mut:
	dwLowDateTime  u32
	dwHighDateTime u32
}

struct C.itimerspec #

struct C.itimerspec {
pub mut:
	it_interval C.timespec
	it_value    C.timespec
}

struct C.timespec #

Available on Unix only.

struct C.timespec {
pub mut:
	tv_sec  i64
	tv_nsec i64
}

Available on Windows only.

struct C.timespec {
pub:
	tv_sec  i64
	tv_nsec i64
}

in most systems, these are __quad_t, which is an i64

struct C.timeval #

struct C.timeval {
pub:
	tv_sec  u64
	tv_usec u64
}

C.timeval represents a C time value.

struct C.tm #

Available on Unix only.

struct C.tm {
pub mut:
	tm_sec   i32
	tm_min   i32
	tm_hour  i32
	tm_mday  i32
	tm_mon   i32
	tm_year  i32
	tm_wday  i32
	tm_yday  i32
	tm_isdst i32
	// C `long tm_gmtoff`: pointer-width, which V's `int` already matches (i64 on
	// 64-bit, i32 on 32-bit), unlike the 32-bit C `int` fields above.
	tm_gmtoff int
}

Available on Windows only.

struct C.tm {
pub mut:
	tm_year i32
	tm_mon  i32
	tm_mday i32
	tm_hour i32
	tm_min  i32
	tm_sec  i32
}

struct Location #

@[heap]
struct Location {
pub:
	name string
mut:
	zones       []Zone
	transitions []ZoneTransition
	posix       PosixZoneRule
	has_posix   bool
}

Location contains parsed IANA time zone data.

fn (Location) zone_at #

fn (loc &Location) zone_at(unix_time i64) !Zone

zone_at returns the active zone rule for unix_time.

fn (Location) offset_at #

fn (loc &Location) offset_at(unix_time i64) !int

offset_at returns the UTC offset in seconds for unix_time in the location.

fn (Location) unix_to_local #

fn (loc &Location) unix_to_local(unix_time i64) !Time

unix_to_local resolves a Unix timestamp to a Time in the location.

fn (Location) unix_nanosecond_to_local #

fn (loc &Location) unix_nanosecond_to_local(unix_time i64, nanosecond int) !Time

unix_nanosecond_to_local resolves a Unix timestamp and nanosecond to a Time in the location. The returned Time keeps unix as the absolute UTC epoch instant; the calendar fields are the wall time in loc. is_local stays false. A nanosecond outside 0 .. 999_999_999 is carried into unix_time, as in unix_nanosecond.

struct StopWatch #

struct StopWatch {
mut:
	elapsed u64
	started bool
pub mut:
	start u64
	end   u64
}

StopWatch is used to measure elapsed time.

fn (StopWatch) start #

fn (mut t StopWatch) start()

start starts the stopwatch. If the timer was paused, it continues counting.

fn (StopWatch) restart #

fn (mut t StopWatch) restart()

restart restarts the stopwatch. If the timer was paused, it restarts counting.

fn (StopWatch) stop #

fn (mut t StopWatch) stop()

stop stops the timer, by setting the end time to the current time.

fn (StopWatch) pause #

fn (mut t StopWatch) pause()

pause resets the start time and adds the current elapsed time to elapsed.

fn (StopWatch) elapsed #

fn (t StopWatch) elapsed() Duration

elapsed returns the Duration since the last start call.

struct StopWatchOptions #

@[params]
struct StopWatchOptions {
pub:
	auto_start bool = true
}

struct Time #

@[markused]
struct Time {
	unix i64
	// loc uses nil so existing Time literals remain unzoned; V requires unsafe
	// to initialize a reference field with that sentinel.
	loc &Location = unsafe { nil }
pub:
	year       int
	month      int
	day        int
	hour       int
	minute     int
	second     int
	nanosecond int
	is_local   bool // used to make time.now().local().local() == time.now().local()
}

Time contains various time units for a point in time.

fn (Time) days_from_unix_epoch #

@[inline]
fn (t Time) days_from_unix_epoch() int

days_from_unix_epoch - return the number of days since the Unix epoch 1970-01-01. A detailed description of the algorithm here is in: http://howardhinnant.github.io/date_algorithms.html Note that method will return negative values for days before 1970-01-01.

fn (Time) weekday #

fn (t Time) weekday() Weekday

weekday returns the day of the week of t.

fn (Time) add_date #

fn (t Time) add_date(years int, months int, days int) Time

add_date returns t shifted by the given number of years, months and days, normalizing months and clamping the day to the target month's last day. The time of day, nanoseconds and location are preserved. Ambiguous wall times prefer the input's UTC offset when valid; nonexistent wall times use that offset, normalizing to a nearby valid time.

fn (Time) format #

@[manualfree]
fn (t Time) format() string

format returns a date string in "YYYY-MM-DD HH:mm" format (24h).

fn (Time) format_ss #

@[manualfree]
fn (t Time) format_ss() string

format_ss returns a date string in "YYYY-MM-DD HH:mm:ss" format (24h).

fn (Time) format_ss_milli #

@[manualfree]
fn (t Time) format_ss_milli() string

format_ss_milli returns a date string in "YYYY-MM-DD HH:mm:ss.123" format (24h).

fn (Time) format_ss_micro #

@[manualfree]
fn (t Time) format_ss_micro() string

format_ss_micro returns a date string in "YYYY-MM-DD HH:mm:ss.123456" format (24h).

fn (Time) format_ss_nano #

@[manualfree]
fn (t Time) format_ss_nano() string

format_ss_nano returns a date string in "YYYY-MM-DD HH:mm:ss.123456789" format (24h).

fn (Time) format_rfc3339 #

@[manualfree]
fn (t Time) format_rfc3339() string

format_rfc3339 returns a date string in "YYYY-MM-DDTHH:mm:ss.123Z" format (24 hours, see https://www.rfc-editor.org/rfc/rfc3339.html) RFC3339 is an Internet profile, based on the ISO 8601 standard for for representation of dates and times using the Gregorian calendar. It is intended to improve consistency and interoperability, when representing and using date and time in Internet protocols.

fn (Time) format_rfc3339_micro #

@[manualfree]
fn (t Time) format_rfc3339_micro() string

format_rfc3339_micro returns a date string in "YYYY-MM-DDTHH:mm:ss.123456Z" format (24 hours, see https://www.rfc-editor.org/rfc/rfc3339.html)

fn (Time) format_rfc3339_nano #

@[manualfree]
fn (t Time) format_rfc3339_nano() string

format_rfc3339_nano returns a date string in "YYYY-MM-DDTHH:mm:ss.123456789Z" format (24 hours, see https://www.rfc-editor.org/rfc/rfc3339.html)

fn (Time) hhmm #

@[manualfree]
fn (t Time) hhmm() string

hhmm returns a date string in "HH:mm" format (24h).

fn (Time) hhmmss #

@[manualfree]
fn (t Time) hhmmss() string

hhmmss returns a date string in "HH:mm:ss" format (24h).

fn (Time) hhmm12 #

fn (t Time) hhmm12() string

hhmm12 returns a date string in "hh:mm" format (12h).

fn (Time) ymmdd #

fn (t Time) ymmdd() string

ymmdd returns a date string in "YYYY-MM-DD" format.

fn (Time) ddmmy #

fn (t Time) ddmmy() string

ddmmy returns a date string in "DD.MM.YYYY" format.

fn (Time) md #

fn (t Time) md() string

md returns a date string in "MMM D" format.

fn (Time) custom_format #

fn (t Time) custom_format(s string) string

custom_format returns a date with custom format. YYYY pads nonnegative years to at least four digits; YY pads their final two digits. Negative years retain their existing token formatting.

Category Token Output
Era N BC AD
NN Before Christ, Anno Domini
Year YY 00 01 ... 98 99
YYYY 0000 0001 ... 9999
Quarter Q 1 2 3 4
QQ 01 02 03 04
Qo 1st 2nd 3rd 4th
Month M 1 2 ... 11 12
Mo 1st 2nd ... 11th 12th
MM 01 02 ... 11 12
MMM Jan Feb ... Nov Dec
MMMM January February ... November December
Week of Year w 1 2 ... 52 53
wo 1st 2nd ... 52nd 53rd
ww 01 02 ... 52 53
Day of Month D 1 2 ... 30 31
Do 1st 2nd ... 30th 31st
DD 01 02 ... 30 31
Day of Year DDD 1 2 ... 364 365
DDDo 1st 2nd ... 364th 365th
DDDD 001 002 ... 364 365
Day of Week d 0 1 ... 5 6 (Sun-Sat)
c 1 2 ... 6 7 (Mon-Sun)
dd Su Mo ... Fr Sa
ddd Sun Mon ... Fri Sat
dddd Sunday Monday ... Friday Saturday
AM/PM A AM PM
a am pm
Hour H 0 1 ... 22 23
HH 00 01 ... 22 23
h 1 2 ... 11 12
hh 01 02 ... 11 12
i 0 1 ... 11 12 1 ... 11
ii 00 01 ... 11 12 01 ... 11
k 1 2 ... 23 24
kk 01 02 ... 23 24
Minute m 0 1 ... 58 59
mm 00 01 ... 58 59
Second s 0 1 ... 58 59
ss 00 01 ... 58 59
Offset Z -7 -6 ... +5 +6
ZZ -0700 -0630 ... +0545 +0600
ZZZ -07:00 -06:30 ... +05:45 +06:00

Usage:

println(time.now().custom_format('MMMM Mo YY N kk:mm:ss A')) // output like: January 1st 22 AD 13:45:33 PM

fn (Time) clean #

fn (t Time) clean() string

clean returns a date string in a clean form. It has the following format:- a date string in "HH:mm" format (24h) for current day

  • a date string in "MMM D HH:mm" format (24h) for date of current year
  • a date string formatted with format function for other dates

fn (Time) clean12 #

fn (t Time) clean12() string

clean12 returns a date string in a clean form. It has the following format:- a date string in "h:mm a.m./p.m." format (12h) for current day

  • a date string in "MMM D h:mm a.m./p.m." format (12h) for date of current year
  • a date string formatted with format function for other dates

fn (Time) get_fmt_time_str #

fn (t Time) get_fmt_time_str(fmt_time FormatTime) string

get_fmt_time_str returns a date string with specified FormatTime type.

fn (Time) get_fmt_date_str #

fn (t Time) get_fmt_date_str(fmt_dlmtr FormatDelimiter, fmt_date FormatDate) string

get_fmt_time_str returns a date string with specified FormatDelimiter and FormatDate type.

fn (Time) get_fmt_str #

fn (t Time) get_fmt_str(fmt_dlmtr FormatDelimiter, fmt_time FormatTime, fmt_date FormatDate) string

get_fmt_str returns a date string with specified FormatDelimiter, FormatTime type, and FormatDate type.

fn (Time) utc_string #

@[deprecated: 'use `http_header_string()` instead']
@[deprecated_after: '2026-09-30']
fn (t Time) utc_string() string

utc_string returns a date string in the legacy UTC cookie/header format.

fn (Time) http_header_string #

@[manualfree]
fn (t Time) http_header_string() string

http_header_string returns a date string in the format used in HTTP headers, as defined in RFC 2616. e.g. "Sun, 06 Nov 1994 08:49:37 GMT"

fn (Time) write_http_header #

@[unsafe]
fn (t Time) write_http_header(dst &u8, dst_len int) !

write_http_header writes the 29-byte HTTP-date ("Sun, 06 Nov 1994 08:49:37 GMT", RFC 9110 IMF-fixdate) at dst, which may point into a fixed array or a dynamic array's data, at any offset. dst_len is the number of writable bytes at dst; an error is returned when it is less than http_date_len, so a caller cannot silently overrun its buffer. No allocation on the success path.

fn (Time) push_to_http_header #

fn (t Time) push_to_http_header(mut buffer []u8)

push_to_http_header appends the 29-byte HTTP-date to buffer, as defined in RFC 2616. e.g. "Sun, 06 Nov 1994 08:49:37 GMT"

fn (Time) from_json_number #

fn (mut t Time) from_json_number(raw_number string) !

from_json_string implements a custom decoder for json2 (unix)

fn (Time) from_json_string #

fn (mut t Time) from_json_string(raw_string string) !

from_json_string decodes iso8601/rfc3339/unix values, with or without JSON string quotes.

fn (Time) to_json #

fn (t Time) to_json() string

to_json implements a custom encoder for json2 (rfc3339).

fn (Time) == #

@[inline]
fn (t1 Time) == (t2 Time) bool

operator == returns true if provided time is equal to time

fn (Time) < #

@[inline]
fn (t1 Time) < (t2 Time) bool

operator < returns true if provided time is less than time

fn (Time) - #

@[inline]
fn (lhs Time) - (rhs Time) Duration

Time subtract using operator overloading.

fn (Time) str #

fn (t Time) str() string

str returns the time in the same format as parse expects ("YYYY-MM-DD HH:mm:ss").

fn (Time) strftime #

fn (t Time) strftime(fmt string) string

strftime returns the formatted time using strftime(3).

fn (Time) smonth #

fn (t Time) smonth() string

smonth returns the month name abbreviation.

fn (Time) unix #

@[inline]
fn (t Time) unix() i64

unix returns the UNIX time with second resolution.

fn (Time) local_unix #

@[inline]
fn (t Time) local_unix() i64

local_unix returns the UNIX local time with second resolution. For IANA locations this is the absolute unix instant plus the zone offset active at that instant (wall-clock seconds since epoch in that location).

fn (Time) is_zero #

@[inline]
fn (t Time) is_zero() bool

is_zero returns true when t is the zero value of time.Time.

fn (Time) unix_milli #

@[inline]
fn (t Time) unix_milli() i64

unix_milli returns the UNIX time with millisecond resolution.

fn (Time) unix_micro #

@[inline]
fn (t Time) unix_micro() i64

unix_micro returns the UNIX time with microsecond resolution.

fn (Time) unix_nano #

@[inline]
fn (t Time) unix_nano() i64

unix_nano returns the UNIX time with nanosecond resolution.

fn (Time) add #

fn (t Time) add(duration_in_nanosecond Duration) Time

add returns a new time with the given duration added.

fn (Time) add_seconds #

fn (t Time) add_seconds(seconds int) Time

add_seconds returns a new time struct with an added number of seconds.

fn (Time) add_days #

fn (t Time) add_days(days int) Time

add_days returns a new time struct with an added number of days.

fn (Time) relative #

fn (t Time) relative() string

relative returns a string representation of the difference between t and the current time.

Sample outputs:

// future
now
in 5 minutes
in 1 day
on Feb 17
// past
2 hours ago
last Jan 15
5 years ago

fn (Time) relative_short #

fn (t Time) relative_short() string

relative_short returns a string saying how long ago a time occurred as follows: 0-30 seconds: "now"; 30-60 seconds: "1m"; anything else is rounded to the nearest minute, hour, day, or year

Sample outputs:

// future
now
in 5m
in 1d
// past
2h ago
5y ago

fn (Time) day_of_week #

fn (t Time) day_of_week() int

day_of_week returns the current day as an integer.

fn (Time) week_of_year #

fn (t Time) week_of_year() int

week_of_year returns the current week of year as an integer. follow ISO 8601 standard

fn (Time) year_day #

fn (t Time) year_day() int

year_day returns the current day of the year as an integer. See also #Time.custom_format .

fn (Time) weekday_str #

fn (t Time) weekday_str() string

weekday_str returns the current day as a string 3 letter abbreviation.

fn (Time) long_weekday_str #

fn (t Time) long_weekday_str() string

long_weekday_str returns the current day as a string.

fn (Time) debug #

fn (t Time) debug() string

debug returns detailed breakdown of time (Time{ year: YYYY month: MM day: dd hour: HH: minute: mm second: ss nanosecond: nanos unix: unix is_local: false }).

fn (Time) local_to_utc #

fn (t Time) local_to_utc() Time

local_to_utc converts the receiver t to the corresponding UTC time, if it contains local time. If the receiver already does contain UTC time, it returns it unchanged.

fn (Time) utc_to_local #

fn (u Time) utc_to_local() Time

utc_to_local converts the receiver u to the corresponding local time, if it contains UTC time. If the receiver already does contain local time, it returns it unchanged.

fn (Time) as_local #

fn (t Time) as_local() Time

as_local returns the exact same time, as the receiver t, but with its .is_local field set to true. See also #Time.utc_to_local .

fn (Time) as_utc #

fn (t Time) as_utc() Time

as_utc returns the exact same time, as the receiver t, but with its .is_local field set to false. See also #Time.local_to_utc .

fn (Time) is_utc #

fn (t Time) is_utc() bool

is_utc returns true, when the receiver t is a UTC time, and false otherwise. See also #Time.utc_to_local .

fn (Time) local #

fn (t Time) local() Time

local returns t with the location set to local time.

fn (Time) in #

fn (t Time) in(loc &Location) !Time

in resolves t as a Time in loc.

fn (Time) location #

fn (t Time) location() ?&Location

location returns the IANA location associated with t, if any.

fn (Time) zone #

fn (t Time) zone() !Zone

zone returns the active zone rule for t, if it has an IANA location.

struct TimeParseError #

struct TimeParseError {
	Error
	code    int
	message string
}

TimeParseError represents a time parsing error.

fn (TimeParseError) msg #

fn (err TimeParseError) msg() string

msg implements the IError.msg() method for TimeParseError.

struct Zone #

struct Zone {
pub:
	name   string
	offset int
	is_dst bool
}

Zone describes one time zone rule in an IANA location.