# Constructing a DateTime, DateOnly, or TimeOnly

> Build a temporal value from its components. DateTime.New takes a date, optionally with a time (defaulting to midnight); DateOnly.New takes a calendar date with no time; TimeOnly.New takes a time of day with no date. For a value coming from a string, Parse is the sibling. All run in the browser.

<!-- id: function-datetime-construct · area: function · stability: stable · html: https://osysharp.com/reference/function/datetime-construct/ -->

## Summary        {#summary}
⚠ **There is no `DateOnly.Today`** (nor a `TimeOnly.Now`) — `DateOnly`/`TimeOnly` have no member that reads the
clock. For today's date as a `DateOnly`, take the date part off the current instant instead:
`DateOnly.FromDateTime(DateTime.UtcNow)` (see [Current time (DateTime.UtcNow, DurableClock.Now)](https://osysharp.com/reference/function/current-time/) for `DateTime.UtcNow`/`DurableClock.UtcNow`).

When you have the components rather than a string, these build the value directly. `DateTime.New(y, m, d)`
makes a date at **midnight**, and `DateTime.New(y, m, d, h, mi, s)` includes the time. `DateOnly.New(y, m, d)`
makes a bare calendar date, and `TimeOnly.New(h, m)` / `TimeOnly.New(h, m, s)` makes a bare time of day.
`DateOnly.FromDateTime(dt)` / `TimeOnly.FromDateTime(dt)` split a `DateTime` into its date or time half — the way to
get "today"/"now" as a bare `DateOnly`/`TimeOnly`, since neither has its own clock read.

## Signature      {#signature}
```osy syntax
DateTime.New(<int> year, <int> month, <int> day)                          -> DateTime  // 00:00:00
DateTime.New(<int> year, <int> month, <int> day, <int> hour, <int> minute, <int> second) -> DateTime
DateOnly.New(<int> year, <int> month, <int> day)                          -> DateOnly
TimeOnly.New(<int> hour, <int> minute)                                    -> TimeOnly   // seconds = 0
TimeOnly.New(<int> hour, <int> minute, <int> second)                      -> TimeOnly
DateOnly.FromDateTime(<DateTime> dt)                                      -> DateOnly   // no DateOnly.Today — this is "today"
TimeOnly.FromDateTime(<DateTime> dt)                                      -> TimeOnly   // no TimeOnly.Now — this is "now"
```

## Description    {#description}
`DateTime.New` builds a `DateTime` from whole components. With three arguments the time is **midnight**; the
six-argument form sets the time explicitly. The result is a UTC instant, consistent with the rest of the date
surface ([Current time (DateTime.UtcNow, DurableClock.Now)](https://osysharp.com/reference/function/current-time/) explains why a `DateTime` here is always UTC).

`DateOnly.New` and `TimeOnly.New` build the two "half" values — a date with no time, and a time with no date
([TimeSpan, DateOnly, TimeOnly](https://osysharp.com/reference/types/duration-and-parts/)). `TimeOnly.New` defaults the seconds to `0` when you pass only hours and
minutes.

**Constructing vs parsing.** Use `New` when you *have* the numeric components; use `DateTime.Parse(s)` (and
`DateOnly.Parse` / `TimeOnly.Parse`) when you have a **string** — for example an ISO timestamp from an API.
The parsing side lives with the current-time surface, [Current time (DateTime.UtcNow, DurableClock.Now)](https://osysharp.com/reference/function/current-time/).

These are pure, so they run **in the browser** with no round trip ([Reading a date — Year, Month, Day, Hour, Minute, Second, DayOfWeek, Date](https://osysharp.com/reference/function/date-parts/) reads the
components back off the value you build).

## Examples       {#examples}
```osy title="the first moment of a given month" test app=datetime-new
DateTime MonthStart(int year, int month) {
  return DateTime.New(year, month, 1);      // day 1, midnight
}
```

```osy title="the exact answers, pinned" run app=datetime-new
[Test]
void Datetime_construct() {
  // three args → midnight
  var midnight = DateTime.New(2024, 3, 15);
  Assert.Equal(15, midnight.Day);
  Assert.Equal(0, midnight.Hour);
  Assert.Equal(1, MonthStart(2024, 3).Day);

  // six args → explicit time
  var full = DateTime.New(2024, 3, 15, 13, 45, 30);
  Assert.Equal(13, full.Hour);
  Assert.Equal(30, full.Second);

  // the half values
  Assert.Equal(29, DateOnly.New(2024, 2, 29).Day);    // a valid leap day
  Assert.Equal(45, TimeOnly.New(13, 45).Minute);
  Assert.Equal(0, TimeOnly.New(13, 45).Second);        // seconds default to 0
  Assert.Equal(30, TimeOnly.New(13, 45, 30).Second);

  // "today" as a bare DateOnly — there is no `DateOnly.Today`; split it off the current instant instead
  var today = DateOnly.FromDateTime(DateTime.UtcNow);
  Assert.Equal(DateTime.UtcNow.Year, today.Year);
}
```

## See also       {#see-also}
- [Current time (DateTime.UtcNow, DurableClock.Now)](https://osysharp.com/reference/function/current-time/) — the current instant, and `DateTime.Parse` for building from a string
- [Reading a date — Year, Month, Day, Hour, Minute, Second, DayOfWeek, Date](https://osysharp.com/reference/function/date-parts/) — reading the components back off a value
- [TimeSpan, DateOnly, TimeOnly](https://osysharp.com/reference/types/duration-and-parts/) — the `DateOnly` and `TimeOnly` types
