Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / Function

Building and reading a TimeSpan

new TimeSpan(...) / TimeSpan.FromMilliseconds(n) → TimeSpan · ts.Days/Hours/Minutes/Seconds → int · ts.TotalDays/TotalHours/TotalMinutes/TotalSeconds/TotalMilliseconds → double

How to build a duration and read it back. Construct one with new TimeSpan(...) or a TimeSpan.FromX factory (including TimeSpan.FromMilliseconds); then read either the WHOLE span in one unit — TimeSpan.TotalHours and friends, fractional — or the individual component in each slot — TimeSpan.Hours and friends, whole. The two are easy to confuse. On a negative span every component is negative.

stable2 examples compiled by CIfunctiondatetimetimespanduration

Summary#

A TimeSpan is a duration (TimeSpan (durations)). You build one with new TimeSpan(...) — the call the runtime knows as TimeSpan.New — or a TimeSpan.FromX factory (TimeSpan.FromDays, FromHours, FromMinutes, FromSeconds, TimeSpan.FromMilliseconds). You read it two ways that are easy to mix up: the totals (TimeSpan.TotalDays, TotalHours, TotalMinutes, TotalSeconds, TotalMilliseconds) give the whole span expressed in one unit, and the parts (TimeSpan.Days, Hours, Minutes, Seconds) give the individual component in each slot.

Signature#

new TimeSpan(<int> hours, <int> minutes, <int> seconds)              -> TimeSpan
new TimeSpan(<int> days, <int> hours, <int> minutes, <int> seconds)  -> TimeSpan
TimeSpan.FromMilliseconds(<number> n) -> TimeSpan     // (and FromDays/FromHours/FromMinutes/FromSeconds)

ts.TotalDays / TotalHours / TotalMinutes / TotalSeconds / TotalMilliseconds  -> double   // the WHOLE span, one unit
ts.Days / Hours / Minutes / Seconds  -> int                                              // the component PARTS

Description#

Building a span#

new TimeSpan(h, m, s) and new TimeSpan(d, h, m, s) build a span from whole components. The TimeSpan.FromX factories build one from a single, possibly fractional, quantity: TimeSpan.FromMilliseconds(1500) is one and a half seconds, and TimeSpan.FromDays(1.5) is a day and a half. (The factories are covered alongside the type in TimeSpan (durations); TimeSpan.FromMilliseconds completes the set here.)

Totals vs parts — the distinction that trips people up#

For the span 1 day, 2 hours, 3 minutes, 4 seconds:

Total (whole span, one unit — a double)Part (the component in that slot — an int)
TimeSpan.TotalDays1.085462962962963TimeSpan.Days1
TimeSpan.TotalHours26.051111111111112TimeSpan.Hours2
TimeSpan.TotalMinutes1563.0666666666666TimeSpan.Minutes3
TimeSpan.TotalSeconds93784TimeSpan.Seconds4
TimeSpan.TotalMilliseconds93784000

TotalHours is the entire span measured in hours (26.05…); Hours is just the hours slot (2). Totals are fractional (double); parts are whole (int).

A negative span has negative components#

Subtract a later time from an earlier one and the span is negative. Then every component is negative or zero — TimeSpan.FromHours(-2) has Hours of -2 and Minutes of 0 (not 60), and TotalHours of -2. Do not assume a component is non-negative.

Every one of these is a pure function of the value, so it runs in the browser with no round trip (execution side).

Examples#

// The WHOLE span in minutes — TotalMinutes, not Minutes (which would drop the hours).
int MinutesUntil(DateTime deadline) {
  var left = deadline - DateTime.UtcNow;
  return Convert.ToInt(left.TotalMinutes);
}
[Test]
void TimeSpan_parts_and_totals() {
  var span = new TimeSpan(1, 2, 3, 4);         // 1d 2h 3m 4s

  // component PARTS — the piece in each slot, as ints
  Assert.Equal(1, span.Days);
  Assert.Equal(2, span.Hours);                 // the hours SLOT — not the whole span in hours
  Assert.Equal(3, span.Minutes);
  Assert.Equal(4, span.Seconds);

  // a factory, read back through a part
  Assert.Equal(1, TimeSpan.FromMilliseconds(1500).Seconds);   // 1.5s → the seconds slot is 1

  // a NEGATIVE span: every component is negative or zero, never wrapped positive
  var neg = TimeSpan.FromHours(-2);
  Assert.Equal(-2, neg.Hours);
  Assert.Equal(0, neg.Minutes);
}

See also#

Related

TimeSpan (durations)

`TimeSpan` is the duration type — a length of time, as in C#. Build one with the `TimeSpan.FromX` factories or `new…

TimeSpan, DateOnly, TimeOnly

A duration, a bare date, and a bare time of day. Subtracting two DateTimes gives a TimeSpan; adding one back gives a…

DateTime

A date and time. It is a wall-clock value, not an instant on a timeline, so it is never shifted by anybody's timezone…

execution side

Where a function runs. Osy# infers it from the body: a function that reads data runs on the server, a function that…