# TimeSpan (durations)

> `TimeSpan` is the duration type — a length of time, as in C#. Build one with the `TimeSpan.FromX` factories or `new TimeSpan(…)`, read `.TotalHours`/`.TotalMinutes`/… (fractional) or `.Days`/`.Hours`/… (whole components), and store it on an entity like any scalar. Evaluated in memory.

<!-- id: types-timespan · area: types · stability: preview · html: https://osysharp.com/reference/types/timespan/ -->

## Summary        {#summary}
`TimeSpan` is a **duration** — a length of time — exactly as in C#. It is a first-class scalar: you can declare
a `TimeSpan` local, pass it to a function, and **store it on an entity** (persisted as an interval). Build one
with the `TimeSpan.FromX` factories or the `new TimeSpan(…)` constructor; read its total or component parts
through members.

## Signature      {#signature}
```osy syntax
TimeSpan.FromDays(n) / FromHours(n) / FromMinutes(n) / FromSeconds(n) / FromMilliseconds(n)   // factories
new TimeSpan(hours, minutes, seconds)              // constructor (h/m/s)
new TimeSpan(days, hours, minutes, seconds)        // constructor (d/h/m/s)
ts.TotalDays / TotalHours / TotalMinutes / TotalSeconds / TotalMilliseconds   // fractional whole-span totals (double)
ts.Days / Hours / Minutes / Seconds                // whole component parts (int)
```

## Description    {#description}
A factory takes a numeric count and returns the duration: `TimeSpan.FromHours(2)` is two hours. The constructor
takes whole components — `new TimeSpan(1, 30, 0)` is one hour thirty minutes (h, m, s), and the four-argument
form leads with days.

The **`.TotalX`** members give the whole span measured in that unit, as a fractional `double` — `TimeSpan.FromMinutes(90).TotalHours`
is `1.5`. The **component** members (`.Days`, `.Hours`, `.Minutes`, `.Seconds`) give the whole-number parts of the
breakdown — for `new TimeSpan(1, 2, 30, 0)`, `.Days` is `1` and `.Hours` is `2`.

A `TimeSpan` entity property is stored and read back faithfully:

```osy title="a duration on an entity, and the arithmetic over it" test app=types-timespan
entity WorkItem {
  [Required, MaxLength(200)] string Title;
  TimeSpan Estimate;
}

TimeSpan DefaultEstimate() {
  return new TimeSpan(1, 30, 0);          // 1h30m — the (h, m, s) constructor
}

double EstimateInHours(WorkItem w) {
  return w.Estimate.TotalHours;           // 90 minutes → 1.5
}

TimeSpan Remaining(WorkItem w, TimeSpan spent) {
  return w.Estimate - spent;              // durations subtract, exactly as in C#
}
```

**Arithmetic and comparison** are C#-faithful:

- `dateTime2 - dateTime1` → a `TimeSpan` (how much time elapsed).
- `dateTime + timeSpan` / `dateTime - timeSpan` → a shifted `DateTime`.
- `timeSpan1 + timeSpan2` / `timeSpan1 - timeSpan2` → a `TimeSpan`; `timeSpan * n` scales one.
- `<`, `<=`, `>`, `>=`, `==`, `!=` compare two `TimeSpan`s (and two `DateTime`s).

`TimeSpan` values are computed **in memory** (in function/method bodies). Calling a `TimeSpan` operation — an
arithmetic operator, a factory, or a member — inside a query predicate that lowers to the database is not supported
yet; compute the duration in code.

## Examples       {#examples}
Factories, components, and `DateTime`/`TimeSpan` arithmetic — the window/debounce shape:

```osy title="durations, components, and arithmetic" test app=timespan
double QuotaMinutes() {
  var quota = TimeSpan.FromHours(2);
  return quota.TotalMinutes;                       // 120.0
}

int LeadDays() {
  var span = new TimeSpan(1, 2, 30, 0);            // 1d 2h 30m
  return span.Days;                                // 1
}

TimeSpan Elapsed(DateTime start, DateTime end) {
  return end - start;                              // DateTime − DateTime → TimeSpan
}

bool LongEnough(DateTime start, DateTime end) {
  return (end - start) >= TimeSpan.FromHours(2);   // arithmetic + comparison
}
```

A `TimeSpan` is also a normal entity column:

```osy title="a duration as an entity column" syntax
entity WorkItem {
  string Title;
  TimeSpan Estimate;      // stored as an interval; read back as a TimeSpan
}
```

## See also       {#see-also}
- [Numeric types & literal suffixes](https://osysharp.com/reference/function/numeric-literals/) — the numeric counts the factories take
- [namespace](https://osysharp.com/reference/types/namespace/) — where the built-in value types live
