Time v0.1.0
Installation
Add Time to the [Dependencies] table of your package's Rux.toml:
[Dependencies]
Time = { Namespace = "Rux", Version = "0.1.0" }
Standard packages are declared by hand: the registry does not serve them, so rux add Rux/Time cannot add them.
Dependencies
Core0.1.0FreeBSD0.1.0 (FreeBSD only)Linux0.1.0 (Linux only)macOS0.1.0 (macOS only)Text0.1.0Windows0.1.0 (Windows only)
Guide
Nanosecond durations, monotonic and wall clocks, Gregorian calendar values, and RFC 3339 text.
What it provides
Duration— a span of time exact to the nanosecond, normalized so the fraction is always in [0, 1e9) with the sign carried by the seconds: equality is bytewise, ordering is two comparisons, and arithmetic is a carry. All of it is checked — an overflow at the edge of a 292-billion-year range is a bug in the caller's arithmetic, and gets a report rather than a wrap that turns a timeout into a deadline in the past.InstantandTimestamp— monotonic readings for measuring elapsed time and UTC wall-clock moments for interchange.SleepForwaits against the platform clock without exposing its raw handles, and reports aTimeErrorrather than leaving a wait that did not happen indistinguishable from one that did.Stopwatch— elapsed time on the monotonic clock that can be paused and resumed:Start,Stop,Reset,Restart,IsRunning,Elapsedwhile running or stopped, andLapfor splits that exclude paused time. It measures elapsed time and nothing more; repetition, warm-up and statistics are a benchmarking tool's concern.- Calendar values — validated
DateandTimeOfDayvalues, fixedUtcOffsets,DateTimeconversion, and checked date arithmetic over the proleptic Gregorian calendar. - RFC 3339 and the calendar shapes —
ParseDate,ParseTimeOfDay,ParseDateTimeandParseRfc3339each answer a native fallibleT ! TimeParseError, and every failure carries a zero-based byte offset into the text. The categories are the ones a caller acts on differently: a malformed shape, a month that is not one, a day the month does not have, a time out of range, a fraction too long, and an offset that is not one. Second 60 folds to the last nanosecond of second 59, and formatting never produces it, so the fold is one-way.ParseDurationreads the span form back the same way. - Presentation —
Date,TimeOfDay,UtcOffset,DateTime,OffsetDateTime,DurationandTimestampimplementDisplayandDebug. ADateTimewrites no offset, because it holds none:Zwould claim UTC and the machine's offset would claim a place.OffsetDateTimeis the pairing that carries one and therefore the type that produces RFC 3339. A precision names 0 to 9 fractional digits and truncates; without one the fraction is written to the digits it has, trailing zeros trimmed. - One default per value — a
Timestampis a moment on the calendar and a count of seconds at once, and only the first is what a bare placeholder writes:{}is RFC 3339 in UTC, and{:unix}is the signed second count. A moment outside years 0000 through 9999 has no RFC 3339 text and is refused withValueOutOfRangebefore anything is written, which the second count still spells.InstantimplementsDebugalone, showingInstant(nanoseconds: N): a monotonic reading counts from an origin the system chose at boot and has no text for a reader, only a difference from another reading.
Calendar readers return their parsed values and positioned failures through native fallibles and ?, and the checked constructors and arithmetic (Date::New, PlusDays, Duration.Plus, Instant.Since, ...) return native optionals. They allocate no storage; an embedded date or time keeps its byte offset within the complete input.
All public value receivers borrow with &T. The remaining raw pointers are writable scalar/aggregate output slots and platform FFI addresses, never ownership handles. The package's value types are structurally Copy; descriptive and fallible factories retain names such as Now, FromSeconds, and New.
Waiting, and what is not here
SleepFor is the supported way to wait. It is a clock operation — it blocks the calling thread against the platform clock — and it is the only one v0.1.0 offers, because v0.1.0 has no concurrency support at all. There is no thread creation, no thread identifier, no yield, no lock, no atomic and no channel in any first-party package; see First-Party Packages for why the Sync and Thread packages were withdrawn rather than shipped. A caller that needs those must supply them, and SleepFor does not imply that a second thread exists to be woken.
It waits for the whole span. A signal can cut a Unix wait short, and the loop goes back for what is left rather than returning early — a caller asked for a span, not for a span unless the process happened to receive a signal. Windows takes its interval as a 32-bit millisecond count, which runs out after about 49.7 days, so a longer span is waited for in chunks rather than clamped to the ceiling; MaximumWaitMilliseconds is that ceiling and WaitChunkMilliseconds is the arithmetic, public so that a hundred-day sleep can be checked without waiting a hundred days.
A wait can also simply fail, and SleepFor says so. It returns ! TimeError and succeeds only when the span really elapsed; InvalidDuration means the system refused the request outright, which is a case that used to be indistinguishable from success because a refused wait and a completed one both leave the remainder at zero. A caller with nothing to do about it says so with SleepFor(span) catch { else => {} } — the point is that the information exists.
The system wait is reached through the Waiter interface, and SleepUsing drives whichever one it is given. That is what makes the chunking, the retry and the failure paths testable: a test for a hundred-day sleep must not take a hundred days, and a test for an interrupted sleep cannot arrange a signal.
Index
Interfaces
| Name | Summary |
|---|---|
Waiter | One wait, however the caller reaches the system. |
Types
| Name | Summary |
|---|---|
Date | A calendar date that exists. |
TimeOfDay | A time within a day, to the nanosecond. |
UtcOffset | A fixed shift from UTC, in whole minutes. |
DateTime | A date and a time of day together, in some understood offset. |
TimeParseError | Why text could not be read as a calendar value. |
OffsetDateTime | A date and time together with the offset from UTC they are stated in. |
Duration | A span of time: seconds and a fraction, normalized. |
Instant | A reading of the monotonic clock. |
TimeError | Why a wait did not happen. |
SystemWaiter | The wait every supported system actually provides. |
Stopwatch | A pausable timer over the monotonic clock. |
Timestamp | A moment in UTC: seconds since the Unix epoch and a fraction, normalized. |
Functions
| Name | Summary |
|---|---|
IsLeapYear | Whether year is a leap year: every fourth, except every hundredth, except every four-hundredth. |
DaysInMonth | How many days month holds in year. |
ParseDate | Reads YYYY-MM-DD. |
ParseTimeOfDay | Reads HH:MM:SS with an optional fractional second. |
ParseDateTime | Reads YYYY-MM-DDTHH:MM:SS[.fraction], with no offset. |
ParseRfc3339 | Reads YYYY-MM-DDTHH:MM:SS[.fraction](Z|+HH:MM|-HH:MM). |
ParseDuration | Reads a span written as signed decimal seconds followed by s. |
WaitChunkMilliseconds | How long the next single wait should be asked for, given how much of the span is left. |
SleepUsing<W> | Waits out span through waiter, retrying interruptions and chunking what one wait cannot express. |
SleepFor | Stops the calling thread for at least span. |
Constants
| Name | Summary |
|---|---|
NanosecondsPerSecond | How many nanoseconds one second holds. |
MaximumWaitMilliseconds | The longest interval one system wait may be asked for, in milliseconds. |
MaximumWaitAttempts | How many waits SleepFor will make before giving up on a span that never shrinks. |