Core types quick reference

This is a companion page to the "core concepts", and "choosing between types" pages, describing the fundamental types in Noda Time very briefly, primarily for reference. If you're not familiar with the core concepts, read that page first.


An Instant is a point on a notional global time-line, regardless of calendar system and time zone. It's simply a number of nanoseconds since some arbitrary epoch. Noda Time always uses the Unix epoch, which corresponds to midnight on January 1st 1970 UTC. (This is merely one way of expressing the epoch - it would be equally valid to express it using other calendar systems and time zones; the epoch itself has no notion of a time zone or calendar system.)


An Offset is used to express the difference between UTC and local time. It is always added to a UTC value to obtain a local time, or subtracted from a local time to obtain a UTC value. Values are between 18 hours before UTC and 18 hours after UTC, inclusive. Offset has a granularity of one second; any attempt to create an offset with a value including subseconds is simply truncated to the second.


A CalendarSystem is a way of dividing up a time line into human-friendly units - minutes, hours, days, months, years and so forth. The "default" calendar system in Noda Time is the ISO-8601 calendar, which is basically the Gregorian calendar. Other calendar systems are available, including Julian and Islamic calendars.

A calendar system is orthogonal to a time zone - a time zone effectively just offsets the global time line.


A LocalDateTime is a point on a time line in a particular calendar system, but with no concept of the offset from UTC. In order to identify which specific instant in time a LocalDateTime refers to, you have to supply time zone or offset information.


A LocalDate is simply the date portion of a LocalDateTime - it has no concept of the time of day; it's just a date.


A LocalTime is simply the time portion of a LocalDateTime - it has no concept of the date on which the time occurs; it's just a time.


An OffsetDateTime is a LocalDateTime with an associated Offset - it uniquely identifies an Instant, but because the full time zone information is missing, there's no indication what the local time would be 5 minutes later or earlier, as the offset within the time zone can change. Dates and times are often transmitted between systems using this information - and the offset is often misnamed as a time zone or time zone identifier. It's not - it's just an offset.

OffsetDate and OffsetTime

Introduced in Noda Time 2.3, OffsetDate and OffsetTime are unlikely to be used very often. They're a LocalDate or LocalTime respectively, with an associated offset.

These are far less widely used than OffsetDateTime, but may crop up occasionally - and are officially supported (though rarely used) in XML values, such as <date>2018-03-25+01:00</date> or <time>10:30:00+01:00</time>.


A DateTimeZone (or just time zone) is a mapping between UTC and local times. Many time zones alternate between two offsets over the course of time, based on daylight saving time. To obtain a time zone in Noda Time, you have to choose where the information will come from, via an IDateTimeZoneProvider. Two providers are built into Noda Time - one which uses the tz database (also known as the IANA Time Zone database, or zoneinfo or Olson database) and one to wrap the information provided by the BCL via TimeZoneInfo. Both providers are available through DateTimeZoneProviders as DateTimeZoneProviders.Tzdb and DateTimeZoneProviders.Bcl. Once you've chosen a provider, you can find the identifiers that provider publishes, and fetch any specific time zone by ID.

The IANA time zones page lists the time zones for each release of the time zone database.


A ZonedDateTime is a LocalDateTime within a specific time zone - with the added information of the exact Offset, in case of ambiguity. (During daylight saving transitions, the same local date/time can occur twice.) An alternative way of looking at it is the combination of an Instant, a DateTimeZone, and a CalendarSystem.


A Duration is simply a number of nanoseconds, which can be added to (or subtracted from) an Instant or a ZonedDateTime. A particular value will always represent the same amount of elapsed time, however it's used.


A Period is a number of years, months, weeks, days, hours and so on, which can be added to (or subtracted from) a LocalDateTime, LocalDate or LocalTime. The amount of elapsed time represented by a Period isn't fixed: a period of "one month" is effectively longer when added to January 1st than when added to February 1st, because February is always shorter than January.


An IClock implementation provides information about the current instant. It knows nothing about time zones or calendar systems. For testability, this is defined as an interface; in a production deployment you're likely to use the SystemClock singleton implementation.

Often you may want to repeatedly access the current time or date in a specific time zone. The ZonedClock class helps with this. It wraps an IClock, and is constructed for a specific time zone and calendar system, providing convenience methods to access the current value from as various different types (Instant, LocalDate and so on). The extension methods in NodaTime.Extensions.ClockExtensions can be used to construct a ZonedClock easily.


An Interval is simply two instants - a start and an end. The interval includes the start, and excludes the end, which means that if you have abutting intervals any instant will be in exactly one of those intervals.